欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 前端技术 > javascript >内容正文

javascript

Spring 2.x AOP 配置方式整理

发布时间:2023/12/15 javascript 45 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Spring 2.x AOP 配置方式整理 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

來源:http://www.javaeye.com/topic/320553

 

spring官方手册给出的配置实例。

--------------------------------------------------------------------------------

 

让我们假定你所有的服务层类定义在以 'x.y.service' 为根的包内。 为了让service包(或子包)下所有名字以 'Service' 结尾的类的对象拥有默认的事务语义,你可以做如下的配置:

Xml代码 
  • <aop:config>  
  •   
  •   <aop:pointcut id="serviceOperation"  
  •         expression="execution(* x.y.service..*Service.*(..))"/>  
  •   
  •   <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>  
  •   
  • </aop:config>  
  •   
  • <!-- these two beans will be transactional... -->  
  • <bean id="fooService" class="x.y.service.DefaultFooService"/>  
  • <bean id="barService" class="x.y.service.extras.SimpleBarService"/>  
  •   
  • <!-- ... and these two beans won't -->  
  • <bean id="anotherService" class="org.xyz.SomeService"/> <!-- (not in the right package) -->  
  • <bean id="barManager" class="x.y.service.SimpleBarManager"/> <!-- (doesn't end in 'Service') -->  
  •   
  • <tx:advice id="txAdvice">  
  •   <tx:attributes>  
  •     <tx:method name="get*" read-only="true"/>  
  •     <tx:method name="*"/>  
  •   </tx:attributes>  
  • </tx:advice>  
  •  

    下面的配置示例演示了两个拥有完全不同的事务配置的bean。

    Xml代码 
  • <aop:config>  
  •   
  •   <aop:pointcut id="defaultServiceOperation"  
  •         expression="execution(* x.y.service.*Service.*(..))"/>  
  •   
  •   <aop:pointcut id="noTxServiceOperation"  
  •         expression="execution(* x.y.service.ddl.DefaultDdlManager.*(..))"/>  
  •   
  •   <aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>  
  •   
  •   <aop:advisor pointcut-ref="noTxServiceOperation" advice-ref="noTxAdvice"/>  
  •   
  • </aop:config>  
  •   
  • <!-- this bean will be transactional (see the 'defaultServiceOperation' pointcut) -->  
  • <bean id="fooService" class="x.y.service.DefaultFooService"/>  
  •   
  • <!-- this bean will also be transactional, but with totally different transactional settings -->  
  • <bean id="anotherFooService" class="x.y.service.ddl.DefaultDdlManager"/>  
  •   
  • <tx:advice id="defaultTxAdvice">  
  •   <tx:attributes>  
  •     <tx:method name="get*" read-only="true"/>  
  •     <tx:method name="*"/>  
  •   </tx:attributes>  
  • </tx:advice>  
  •   
  • <tx:advice id="noTxAdvice">  
  •   <tx:attributes>  
  •     <tx:method name="*" propagation="NEVER"/>  
  •   </tx:attributes>  
  • </tx:advice>  
  •  

    在service接口所有的方法上执行的一个业务service方法。这里的定义假设所有的接口都被
    放置在service包内,它们的实现被放置在service包的子包内。
    如果你按照功能对接口进行分组(例如:包com.xyz.someapp.abc.service,com.xyz.def.service),
    则这种情况下这个切点表达式应该是:"execution(* com.xyz.someapp..service.*.*(..))"

    Java代码 
  • /** 
  •  * A business service is the execution of any method defined on a service 
  •  * interface. This definition assumes that interfaces are placed in the 
  •  * "service" package, and that implementation types are in sub-packages. 
  •  *  
  •  * If you group service interfaces by functional area (for example,  
  •  * in packages com.xyz.someapp.abc.service and com.xyz.def.service) then 
  •  * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))" 
  •  * could be used instead. 
  •  * 
  •  * Alternatively, you can write the expression using the 'bean' 
  •  * PCD, like so "bean(*Service)". (This assumes that you have 
  •  * named your Spring service beans in a consistent fashion.) 
  • */  
  • @Pointcut"execution(* com.xyz.someapp.service.*.*(..))")  
  • public void businessService() {}  
  •  

    在dao接口上定义的所有方法内执行一个数据访问操作。这个定义假设所有的dao接口定义
    在dao包内,实现被放置在了子包内。

    Java代码 
  • /** 
  •  * A data access operation is the execution of any method defined on a  
  •  * dao interface. This definition assumes that interfaces are placed in the 
  •  * "dao" package, and that implementation types are in sub-packages. 
  • */  
  • @Pointcut"execution(* com.xyz.someapp.dao.*.*(..))")  
  • public void dataAccessOperation() {}  
  •  

    任何一个名字以“set”开始的方法的执行:

    Xml代码 
  • execution(* set*(..))  
  •  

    AccountService 接口定义的任意方法的执行:

    Xml代码 
  • execution(* com.xyz.service.AccountService.*(..))  
  •  

    在service包中定义的任意方法的执行:

    Xml代码 
  • execution(* com.xyz.service.*.*(..))  
  •  

    在service包或其子包中定义的任意方法的执行:

    Xml代码 
  • execution(* com.xyz.service..*.*(..))  
  •  

     

    其他的例子: 
    -------------------------------------------------------------------------------- 

    两个数据源,两个数据库事务拦截器,两个数据库事物切点。
    execution组合表达式表述数据库事务切点:
    大部分service类的方法使用数据源txManager-datasourceone,对应事物切点txPointcut-datasourceone,事物拦截器txAdvice-datasourceone;
    service层PublishService类的几个方法使用数据源txManager-datasourcetwo,对应事物切点txPointcut-datasourcetwo,事物拦截器txAdvice-datasourcetwo;
    一个自定义方法拦截器RuntimeLogInterceptor(拦截每个方法,并记录每个方法的执行日志),拦截切点runtimeLogInterceptorPoint;

    Xml代码 
  • <!-- 数据源1事务管理器 -->  
  • <bean id="txManager-datasourceone" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  •   <property name="dataSource" ref="DataSource"/>  
  • </bean>  
  •   
  • <!-- 数据源2事务管理器 -->  
  • <bean id="txManager-datasourcetwo" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  •   <property name="dataSource" ref="srcDataSource"/>  
  • </bean>  
  •       
  • <!-- 数据源1事务拦截器 -->  
  • <tx:advice id="txAdvice-datasourceone" transaction-manager="txManager-datasourceone" >  
  •   <tx:attributes>  
  •     <tx:method name="get*" read-only="true"/>  
  •     <tx:method name="*"/>  
  •   </tx:attributes>  
  • </tx:advice>  
  •   
  • <!-- 数据源2事务拦截器 -->  
  • <tx:advice id="txAdvice-datasourcetwo" transaction-manager="txManager-datasourcetwo" >  
  •   <tx:attributes>  
  •     <tx:method name="get*" read-only="true"/>  
  •     <tx:method name="*"/>  
  •   </tx:attributes>  
  • </tx:advice>  
  •   
  • <!-- aop配置 强制使用cglib代理 -->  
  • <aop:config proxy-target-class="true">  
  •   
  •   <!-- datasourceone 数据库事务管理切点   
  •        包含的方法:service包(或子包)下所有名字以 'Service' 结尾的类内所有的方法。  
  •        不包含的方法:x.y.service包下PublishService类的getResCategory(..)方法,  
  •        getEditorResList(..)方法,updateResbackrmd(..)方法  
  •   -->  
  •   <aop:pointcut id="txPointcut-datasourceone"   
  •     expression="execution(* x.y.service..*Service.*(..))   
  •       and !execution(* x.y.service.PublishService.getResCategory(..))   
  •       and !execution(* x.y.service.PublishService.getEditorResList(..))   
  •       and !execution(* x.y.service.PublishService.updateResbackrmd(..))"/>  
  •   
  •   <!-- datasourcetwo 数据库事务管理切点   
  •        包含的方法:x.y.service包PublishService类的getResCategory(..)方法,  
  •        getEditorResList(..)方法,updateResbackrmd(..)方法。  
  •   -->                                                  
  •   <aop:pointcut id="txPointcut-datasourcetwo"   
  •     expression="execution(* x.y.service.PublishService.getResCategory(..))   
  •       or execution(* x.y.service.PublishService.getEditorResList(..))   
  •       or execution(* x.y.service.PublishService.updateResbackrmd(..))"/>  
  •   
  •   <!-- 运行日志拦截点   
  •        包含的方法:service包(或子包)下所有名字以 'Service' 结尾的类内所有的方法。  
  •        不包含的方法:x.y.service包RuntimeLogService类createRuntimeLogBeforeRequest(..)方法,  
  •     getRuntimeLog(..)方法,setRuntimeLog(..)方法,completeRuntimeLogAfterRequest(..)方法。  
  •   -->  
  •   <aop:pointcut id="runtimeLogInterceptorPoint"   
  •     expression="execution(* x.y.service..*Service.*(..))   
  •       and !execution(* x.y.service.RuntimeLogService.createRuntimeLogBeforeRequest(..))   
  •       and !execution(* x.y.service.RuntimeLogService.getRuntimeLog(..))   
  •       and !execution(* x.y.service.RuntimeLogService.setRuntimeLog(..))   
  •       and !execution(* x.y.service.RuntimeLogService.completeRuntimeLogAfterRequest(..))"/>  
  •               
  •   <!-- 运行日志拦截 -->  
  •   <aop:advisor advice-ref="RuntimeLogInterceptor" pointcut-ref="runtimeLogInterceptorPoint"/>  
  •   <!-- datasourceone,datasourcetwo数据库事务拦截 -->  
  •   <aop:advisor advice-ref="txAdvice-datasourceone" pointcut-ref="txPointcut-datasourceone"/>  
  •   <aop:advisor advice-ref="txAdvice-datasourcetwo" pointcut-ref="txPointcut-datasourcetwo"/>  
  •   
  • </aop:config>  
  •  

    总结一下: 
    --------------------------------------------------------------------------------

     

    1,pointcut既可以定义在一个接口上面(表示实现该接口的类方法将被拦截),同时也可以定义在一个类上面(无接口的情
       况,需要强制使用cglib)。在接口上面定义pointcut时无需关心接口实现类的具体位置,只需要定义被拦截的接口及方
       法位置。

    2,常见的情况:
    x.y.service..*Service.*(..)
    x.y.service —— 包“x.y.service”
    x.y.service.. —— 包“x.y.service”及其子包例如:“x.y.service.abc”,“x.y.service.def”,“x.y.service.ghi”,“x.y.service.jkl”。。。
    *Service —— 定义接口(或没有实现接口的类,需要使用cglib代理)表达式;所有以Service结尾的类或接口,注意不是所有以Service结尾的包名。
    *(..) —— 定义方法名,方法参数表达式;任意方法的名称,任意方法参数。

    com.xyz.service.*.*(..)
    com.xyz.service —— 包“com.xyz.service”
    *.*(..) —— 任意接口(或没有实现接口的类,需要使用cglib代理),任意方法,任意参数
    在service包下定义的任意方法的执行。

    com.xyz.service..*.*(..)
    com.xyz.service —— 包“com.xyz.service”
    com.xyz.service.. ——包“com.xyz.service”及其子包
    *.*(..) —— 任意接口(或没有实现接口的类,需要使用cglib代理),任意方法,任意参数

    总结

    以上是生活随笔为你收集整理的Spring 2.x AOP 配置方式整理的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。