首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Spring 2.x AOP 配备方式整理

2012-11-21 
Spring 2.x AOP 配置方式整理spring官方手册给出的配置实例。-------------------------------------------

Spring 2.x AOP 配置方式整理

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

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

?

让我们假定你所有的服务层类定义在以 <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" read-only="true"/> <tx:method name="*"/> </tx:attributes></tx:advice>?

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

<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" 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.*.*(..))"

/** * 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包内,实现被放置在了子包内。

/** * 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”开始的方法的执行:

execution(* set*(..))

?

execution(* com.xyz.service.AccountService.*(..))

?

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

execution(* com.xyz.service.*.*(..))

?

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

execution(* com.xyz.service..*.*(..))

?

?

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

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

<!-- 数据源1事务管理器 --><bean id="txManager-datasourceone" ref="DataSource"/></bean><!-- 数据源2事务管理器 --><bean id="txManager-datasourcetwo" 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-    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代理),任意方法,任意参数


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

1 楼 fxyc 2009-01-27   正学习Spring中,谢谢LZ的分享 2 楼 oopye 2012-01-10   感谢LZ分享,因为execution问题被困了好几天,查英文文档又没看懂

最后把com.yc.biz.*.*(..)改成com.yc.biz..*.*(..)就可以了,就是因为没有把子包纳入事务啊 3 楼 oopye 2012-01-10   oopye 写道感谢LZ分享,因为execution问题被困了好几天,查英文文档又没看懂

最后把com.yc.biz . *.*(..)改成com.yc.biz .. *..*(..)就可以了,就是因为没有把子包纳入事务啊