Chinaunix首页 | 论坛 | 博客
  • 博客访问: 594682
  • 博文数量: 68
  • 博客积分: 5070
  • 博客等级: 大校
  • 技术积分: 1312
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-11 14:20
文章分类

全部博文(68)

文章存档

2011年(3)

2010年(30)

2009年(17)

2008年(18)

我的朋友

分类: Java

2010-08-10 14:30:00

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

Xml代码 复制代码
  1. <aop:config>  
  2.   
  3.   <aop:pointcut id="serviceOperation"  
  4.         expression="execution(* x.y.service..*Service.*(..))"/>  
  5.   
  6.   <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>  
  7.   
  8. aop:config>  
  9.   
  10.   
  11. <bean id="fooService" class="x.y.service.DefaultFooService"/>  
  12. <bean id="barService" class="x.y.service.extras.SimpleBarService"/>  
  13.   
  14.   
  15. <bean id="anotherService" class="org.xyz.SomeService"/>   
  16. <bean id="barManager" class="x.y.service.SimpleBarManager"/>   
  17.   
  18. <tx:advice id="txAdvice">  
  19.   <tx:attributes>  
  20.     <tx:method name="get*" read-only="true"/>  
  21.     <tx:method name="*"/>  
  22.   tx:attributes>  
  23. tx:advice>  
 

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

Xml代码 复制代码
  1. <aop:config>  
  2.   
  3.   <aop:pointcut id="defaultServiceOperation"  
  4.         expression="execution(* x.y.service.*Service.*(..))"/>  
  5.   
  6.   <aop:pointcut id="noTxServiceOperation"  
  7.         expression="execution(* x.y.service.ddl.DefaultDdlManager.*(..))"/>  
  8.   
  9.   <aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>  
  10.   
  11.   <aop:advisor pointcut-ref="noTxServiceOperation" advice-ref="noTxAdvice"/>  
  12.   
  13. aop:config>  
  14.   
  15.   
  16. <bean id="fooService" class="x.y.service.DefaultFooService"/>  
  17.   
  18.   
  19. <bean id="anotherFooService" class="x.y.service.ddl.DefaultDdlManager"/>  
  20.   
  21. <tx:advice id="defaultTxAdvice">  
  22.   <tx:attributes>  
  23.     <tx:method name="get*" read-only="true"/>  
  24.     <tx:method name="*"/>  
  25.   tx:attributes>  
  26. tx:advice>  
  27.   
  28. <tx:advice id="noTxAdvice">  
  29.   <tx:attributes>  
  30.     <tx:method name="*" propagation="NEVER"/>  
  31.   tx:attributes>  
  32. tx:advice>  
 

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

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

 

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

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

 

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

Xml代码 复制代码
  1. execution(* set*(..))  

 

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

Xml代码 复制代码
  1. execution(* com.xyz.service.AccountService.*(..))  

 

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

Xml代码 复制代码
  1. execution(* com.xyz.service.*.*(..))  

 

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

Xml代码 复制代码
  1. execution(* com.xyz.service..*.*(..))  

 

 

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


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

Xml代码 复制代码
  1.   
  2. <bean id="txManager-datasourceone" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  3.   <property name="dataSource" ref="DataSource"/>  
  4. bean>  
  5.   
  6.   
  7. <bean id="txManager-datasourcetwo" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  8.   <property name="dataSource" ref="srcDataSource"/>  
  9. bean>  
  10.        
  11.   
  12. <tx:advice id="txAdvice-datasourceone" transaction-manager="txManager-datasourceone" >  
  13.   <tx:attributes>  
  14.     <tx:method name="get*" read-only="true"/>  
  15.     <tx:method name="*"/>  
  16.   tx:attributes>  
  17. tx:advice>  
  18.   
  19.   
  20. <tx:advice id="txAdvice-datasourcetwo" transaction-manager="txManager-datasourcetwo" >  
  21.   <tx:attributes>  
  22.     <tx:method name="get*" read-only="true"/>  
  23.     <tx:method name="*"/>  
  24.   tx:attributes>  
  25. tx:advice>  
  26.   
  27.   
  28. <aop:config proxy-target-class="true">  
  29.   
  30.     
  31.   <aop:advisor advice-ref="RuntimeLogInterceptor" pointcut-ref="runtimeLogInterceptorPoint"/>  
  32.     
  33.   <aop:advisor advice-ref="txAdvice-datasourceone" pointcut-ref="txPointcut-datasourceone"/>  
  34.   <aop:advisor advice-ref="txAdvice-datasourcetwo" pointcut-ref="txPointcut-datasourcetwo"/>  
  35.   
  36. 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代理),任意方法,任意参数


如果总结的有错误,欢迎大家指正。

阅读(2208) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~