Spring 2.X 中AOP的简明教程

和Spring1.X相比,Spring2.X使用AspectJ的语法来声明AOP,这使得它更“标准”,更灵活了。仍是那句话,若是你不了解AspectJ而且打算使用Spring2.X的AspectJ式AOP,那就学学AspectJ吧,这方面的书仍是不少了。   Spring2.X下的切面有两种实现方式,一种是以Java文件定义切面(其只是普通的Java类),而后在配置文件中声明定义的切面;另外一种是在Java类中引入和AOP相关的元数据(注释)。   先介绍第一种配置方式。须要指出的是,Spring2.X的beans名称空间和Spring1.X有所不一样,它采用了Schema而不是DTD(也可采用DTD方式,具体的请参考文档)。仍是引入毫无心义的日志切面,定义的切面类LogingAspect 以下: public class LogingAspect {  public void logMethod(JoinPoint jp){   System.err.println(jp.getTarget().getClass());   System.err.println(jp.getSignature().getName());  } }   同时在配置文件中以下配置: <bean id = " logAspectTarget " class = " hibernatesample.service.util.LogingAspect "> </ bean> <aop:config> <aop:aspect id = " logAspect " ref = " logAspectTarget "> <aop:pointcut id = " businessService " expression = " execution(* hibernatesample.service.*.*(..)) " /> <aop:after pointcut - ref = " businessService " method = " logMethod " /> </ aop:aspect> </ aop:config>    对于上面的切面,切入点businessService是在配置文件中声明的,其表达式采用了 AspectJ的语法,LogingAspect 类中logMethod(JoinPoint jp)方法根据配置文件信息可知其是after通知,方法的JoinPoint参数不是必须的,它是来自于AspectJ的实用类,这里用它不过输出一些 和链接点有关的信息。固然,在Spring2.X中,切入点和通知能更灵活的使用,咱们能够如AspectJ同样传递参数给通知。若是须要在 Service中引入事务功能,须要以下配置事务通知: <tx:advice id = " txAdvice " transaction - manager = " transactionManager "> <tx:attributes> <tx:method name = " get* " read - only = " true " /> <tx:method name = " find* " read - only = " true " /> <tx:method name = " * " /> </ tx:attributes> </ tx:advice> <aop:config> <aop:pointcut id = " demoServiceMethods " expression = " execution(* hibernatesample.service.*.*(..)) " /> <aop:advisor advice - ref = " txAdvice " pointcut - ref = " demoServiceMethods " /> <aop:aspect id = " logAspect " ref = " logAspectTarget "> <aop:pointcut id = " businessService " expression = " execution(* hibernatesample.service.*.*(..)) " /> <aop:after pointcut - ref = " businessService " method = " logMethod " /> </ aop:aspect> </ aop:config>   完成上面的工做至关于完成了 Spring1.X 的 自动代理。 咱们接下来须要定义的任何 Service Bean 均可以很纯粹很纯粹了: <bean id ="accountService" class ="hibernatesample.service.impl.AccountServiceImpl"> <property name ="accountDAO" ref ="accountDAO"></ property> </ bean>   第二种实现 AOP 的方式和第一种相比,只是在 LogingAspect 中加入了注释,而省去了配置文件中和 LogingAspect 相关的配置。从新编写的 LogingAspect 以下: @Aspect public class LogingAspect { @Pointcut( " execution(* hibernatesample.service.*.*(..)) " ) public void businessService(){} @After( " businessService() " ) public void logMethod(JoinPoint jp){  System.err.println(jp.getTarget().getClass());  System.err.println(jp.getSignature().getName()); } }   而简化后的配置文件能够去除上面的以下和 logAspect 相关的配置信息: <aop:aspect id ="logAspect" ref ="logAspectTarget"> <aop:pointcut id ="businessService" expression ="execution(* hibernatesample.service.*.*(..))" /> <aop:after pointcut-ref ="businessService" method ="logMethod" /> </ aop:aspect> <bean id ="logAspectTarget" class ="hibernatesample.service.util.LogingAspect"></ bean>   尚未完,为了使 Spring 应用 LogingAspect 的注释,须要在配置文件中添上 <aop:aspectj-autoproxy/>   若是以为事务的配置没有使用注释更简洁(我倒不会有这样的想法,毕竟在配置文件中声明的事务只是那么固定的几段,除非做用于类上的事务逻辑上很复杂),也可使用Spring提供的事务注释做用于类文件上,这但是更细粒度的事务声明了。                                             --转载至程式先锋网站[url]www.javabiz.cn[/url]
相关文章
相关标签/搜索