SpringAOP基本知识及拦截器.doc

上传人:牧羊曲112 文档编号:4220139 上传时间:2023-04-10 格式:DOC 页数:35 大小:100.50KB
返回 下载 相关 举报
SpringAOP基本知识及拦截器.doc_第1页
第1页 / 共35页
SpringAOP基本知识及拦截器.doc_第2页
第2页 / 共35页
SpringAOP基本知识及拦截器.doc_第3页
第3页 / 共35页
SpringAOP基本知识及拦截器.doc_第4页
第4页 / 共35页
SpringAOP基本知识及拦截器.doc_第5页
第5页 / 共35页
点击查看更多>>
资源描述

《SpringAOP基本知识及拦截器.doc》由会员分享,可在线阅读,更多相关《SpringAOP基本知识及拦截器.doc(35页珍藏版)》请在三一办公上搜索。

1、原理AOP(Aspect Oriented Programming),也就是面向方面编程的技术。AOP基于IoC基础,是对OOP的有益补充。AOP将应用系统分为两部分,核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的方面Crosscutting enterprise concerns,例如,所有大中型应用都要涉及到的持久化管理(Persistent)、事务管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging)等。AOP正在成为软件开发的下一个光环。使用AOP,你可以

2、将处理aspect的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。Spring framework是很有前途的AOP技术。作为一种非侵略性的、轻型的AOP framework,你无需使用预编译器或其他的元标签,便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP framework,其他人还是像往常一样编程。AOP概念让我们从定义一些重要的AOP概念开始。 方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现。 连

3、接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。 通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。 切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。 引入(Introduction):添加方法或字段到被通知的类。Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使

4、任何对象实现IsModified接口,来简化缓存。 目标对象(Target Object):包含连接点的对象,也被称作被通知或被代理对象。 AOP代理(AOP Proxy):AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。 编织(Weaving):组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。各种通知类型包括: Around通知:包围一个连接点的通知,如方法调用。这是最强大的通知。Aroud通知在方法调用前后完成自定义的行为,

5、它们负责选择继续执行连接点或通过返回它们自己的返回值或抛出异常来短路执行。 Before通知:在一个连接点之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。 Throws通知:在方法抛出异常时执行的通知。Spring提供强制类型的Throws通知,因此你可以书写代码捕获感兴趣的异常(和它的子类),不需要从Throwable或Exception强制类型转换。 After returning通知:在连接点正常完成后执行的通知,例如,一个方法正常返回,没有抛出异常。Around通知是最通用的通知类型。大部分基于拦截的AOP框架(如Nanning和Jboss 4)只提供Aroun

6、d通知。如同AspectJ,Spring提供所有类型的通知,我们推荐你使用最 为合适的通知类型来实现需要的行为。例如,如果只是需要用一个方法的返回值来更新缓存,你最好实现一个after returning通知,而不是around通知,虽然around通知也能完成同样的事情。使用最合适的通知类型使编程模型变得简单,并能减少潜在错 误。例如,你不需要调用在around通知中所需使用的MethodInvocation的proceed()方法,因此就调用失败。切入点的概念是AOP的关键,它使AOP区别于其他使用拦截的技术。切入点使通知独立于OO的层次选定目标。例如,提供声明式事务管理的around通知

7、可以被应用到跨越多个对象的一组方法上。 因此切入点构成了AOP的结构要素。拦截器(也称拦截机) 拦截机 (Interceptor), 是 AOP (Aspect-Oriented Programming) 的另一种叫法。AOP本身是一门语言,只不过我们使用的是基于JAVA的集成到Spring 中的 SpringAOP。同样,我们将通过我们的例子来理解陌生的概念。 接口类Java代码 1. packagecom.test.TestSpring3;2. 3. publicinterfaceUserService/被拦截的接口4. .5. publicvoidprintUser(Stringuser

8、);6. 7. 实现类Java代码 1. packagecom.test.TestSpring3;2. 3. publicclassUserServiceImpimplementsUserService/实现UserService接口4. .5. publicvoidprintUser(Stringuser).6. System.out.println(printUseruser:+user);/显示user7. 8. 9. 10. AOP拦截器Java代码 1. packagecom.test.TestSpring3;2. 3. importorg.aopalliance.intercept

9、.MethodInterceptor;4. importorg.aopalliance.intercept.MethodInvocation;5. 6. publicclassUserInterceptorimplementsMethodInterceptor7. /AOP方法拦截器8. .9. 10. publicObjectinvoke(MethodInvocationarg0)throwsThrowable.11. 12. try.13. 14. if(arg0.getMethod().getName().equals(printUser)15. /拦截方法是否是UserService接

10、口的printUser方法16. .17. Objectargs=arg0.getArguments();/被拦截的参数18. System.out.println(user:+args0);19. arg0.getArguments()0=hello!;/修改被拦截的参数20. 21. 22. 23. System.out.println(arg0.getMethod().getName()+-!);24. returnarg0.proceed();/运行UserService接口的printUser方法25. 26. catch(Exceptione).27. throwe;28. 29.

11、 30. 31. 32. 测试类Java代码 1. packagecom.test.TestSpring3;2. 3. importorg.springframework.beans.factory.BeanFactory;4. 5. importorg.springframework.beans.factory.xml.XmlBeanFactory;6. importorg.springframework.context.ApplicationContext;7. importorg.springframework.context.support.ClassPathXmlApplicatio

12、nContext;8. importorg.springframework.context.support.FileSystemXmlApplicationContext;9. importorg.springframework.core.io.ClassPathResource;10. importorg.springframework.core.io.Resource;11. importorg.springframework.web.context.support.WebApplicationContextUtils;12. 13. publicclassTestInterceptor.

13、14. 15. publicstaticvoidmain(Stringargs).16. ApplicationContextctx=newFileSystemXmlApplicationContext(17. classpath:applicationContext.xml);18. /ApplicationContextctx=newClassPathXmlApplicationContext(applicationContext.xml);19. 20. UserServiceus=(UserService)ctx.getBean(userService);21. us.printUse

14、r(shawn);22. 23. 24. 25. 配置文件 Xml代码 1. 2. 3. 4. 6. 7. 8. 9. 11. 12. 13. com.test.TestSpring3.UserService14. 15. 16. 17. 18. 19. 20. 21. 22. userInterceptor23. 24. 25. 26. 27. 28. 输出: user:shawn printUser-! printUseruser:hello!结论:调用方法的时候传入的值被拦截修改了.拦截器中的事务管理(事务拦截机)如果不采用拦截机的机制时,在使用JDBC进行数据库访问时,存在两种情况:

15、自动提交 这是JDBC驱动默认的模式,每次数据库操作(CRUD)成功完成后,都作为一个单独的事务自动提交,如果未成功完成,即抛出了 SQLException 的话,仅最近的一个操作将回滚。 非自动提交 这是想更好的控制事务时需要程序地方式进行控制: o 在进行该事务单元的任何操作之前 setAutoCommit(false) o 在成功完成事务单元后 commit() o 在异常发生后 rollback()自动提交模式是不被推荐的,因为每个操作都将产生一个事务点,这对于大的应用来说性能将受到影响;再有,对于常见的业务逻辑,这种模式显得无能为力。比如:转帐,从A帐户取出100元,将其存入B帐户;

16、如果在这两个操作之间发生了错误,那么用户A将损失了100元,而本来应该给帐户B的,却因为失败给了银行。所以,建议在所有的应用中,如果使用 JDBC 都将不得不采用非自动提交模式(你们要能发现了在我们的 JDBC 那个例子中,我们采用的就是自动提交模式,我们是为了把精力放在JDBC上,而不是事务处理上),即我们不得不在每个方法中:Java代码 1. try2. /在获得连接后,立即通过调用setAutoCommit(false)将事务处理置为非自动提交模式/PrepareQuerytofetchtheuserInformation3. pst=conn.prepareStatement(find

17、ByName);4. /.mit();5. catch(Exceptionex)6. conn.rollback();7. throwex;8. finally9. try10. /CloseResultSetandStatement11. if(rset!=null)rset.close();12. if(pst!=null)pst.close();13. catch(Exceptionex)14. ex.printStackTrace();15. thrownewException(SQLErrorwhileclosingobjects=+ex.toString();16. 17. 18.

18、 这样代码在AOP的倡导者看来是“肮脏”的代码。他们认为,所有的与事务有关的方法都应当可以集中配置(见声明性事务控制),并自动拦截,程序应当关心他们的主要任务,即商业逻辑,而不应和事务处理的代码搅和在一起。我先看看 Spring 是怎么做到拦截的:1 Spring 内置支持的事务处理拦截机这里因为要用到JpetStore项目中的代码,我们将 applicationContext.xml 全部内容列出: WEB-INF/mail.properties WEB-INF/jdbc.properties 这个配置比想象的要简单的多:Xml代码 1. 2. 6. 7. 8. 9. 1. 所有的拦截机配置

19、都放在 配置元素中.2. 下面还是需要理解一下几个有关AOP的专用名词,不过,是挺抽象的,最好能会意出其的用意 pointcut 切入点,比如:updateAccount 方法需要进行事务管理,则这个切入点就是“执行方法体”(execution)。Spring 所有支持的切入点类型在都在 Spring reference: 6.2.3.1. Supported Pointcut Designators 中列出了。 advice 要对这个切入点进行什么操作,比如事务控制 advisor Spring 特有的概念,将上两个概念合到一个概念中来,即一个 advisor 包含了一个切入点及对这个切入点

20、所实施的操作。 因为 方法执行切入点 execution 为最常见的切入点类型,我们着重介绍一下,execution 的完全形式为:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)这是一个正则表达式,其中由 ? 结尾的部分是可选的。翻译过来就是:执行(方法访问修饰符? 方法返回类型 声明类型? 方法名(方法参数类型) 抛出异常?)所有的这些都是用来定义执行切入点,即那些方法应该被侯选为切入点: 方法访问修饰符 即 public, private 等等 方法返回类型 即方法返回的类型,如 void, String 等等 声明类型 1.5的语法,现在可以先忽略它 方法名 方法的名字 方法参数类型 方法的参数类型 抛出异常 方法声明的抛出的异常 例如,所有dao代码被定义在包 com.xyz.dao及子包 com.xyz.dao.hibernate, 或者其它,如果还有的话,子包中, 里面定义的

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号