Spring 2.x AOP声明式配置
来源:互联网 发布:中国税务网络大学首页 编辑:程序博客网 时间:2024/06/04 00:25
public class People{
public String SayHello(String str){
System.out.println(this.getClass().getName()+ "说:"+str);
return str;
}
}
// import省略
public class TestMain {
public static void main(String[] args) {
// 实例化Spring IoC容器
ApplicationContext ac = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 获取受管Bean的实例
People p = (People) ac.getBean("TestBean");
p.SayHello("传入的参数值");
}
}
import org.aspectj.lang.JoinPoint;
public class MyAspect {
public void beforeAdvice(JoinPoint point) {
System.out.println("前置通知被触发:" + point.getTarget().getClass().getName()+ "将要" + point.getSignature().getName());
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="MyAspect" class="aop.test.MyAspect" />
<bean id="TestBean" class="aop.test.People" />
<aop:config proxy-target-class="true">
<aop:aspect ref="MyAspect" order="0" id="Test">
<aop:pointcut id="testPointcut"
expression="execution(* aop..*(..))" />
<aop:before pointcut-ref="testPointcut"
method="beforeAdvice" />
</aop:aspect>
</aop:config>
</beans>
在基于AOP命名空间的Spring AOP中,要声明一个切面,需要使用<aop:config/>的子标签<aop:aspect>。<aop: aspect>标签有一个ref属性必须被赋值,它用于指定和该切面关联的受管Bean.正如上例所示,MyAspect该Bean对应的java类是一个普通的java类,在该类中定义了切面的通知方法。此外,<aop:aspect>标签还有两个可选的order属性和id属性,order属性用于指定该切面的加载顺序,id属性用于标识该切面。
要声明一个切入点,可以使用<aop:aspect>的子标签<aop:pointcut>,在Spring2.5中它有两个属性id和expression,分别用于标示该切入点和设定该切入点表达式。如上例.
和@AspectJ一样,基于AOP命名空间的配置也可以定义五种通知类型,并且使用方式和特性类似。与@AspectJ不同的是,配置信息从Annotation中转移到了xml配置文件。
声明一个前置通知可以使用<aop:aspect>的子标签<aop:before/>。该标签的属性说明如下表:
<aop:pointcut id="testPointcut"
expression="execution(* aop.test.TestBean.*(..))"/>
<aop:before pointcut-ref="testPointcut" method="beforeAdvice"/>
</aop:aspect>
声明一个后置通知使用<aop:after/>标签,它的属性等和<aop:before/>标签类似,下面是范例:
<aop:pointcut id="testPointcut"
expression="execution(* aop.test.TestBean.*(..))" />
<aop:after pointcut-ref="testPointcut" method="AfterAdvice"/>
</aop:aspect>
<aop:after-returning/>标签可以声明一个返回后通知,该标签的属性和<aop:before/>相比它多了一个returning属性。该属性的意义类似于@AfterReturning注解的returning属性,用于将链接点的返回值传给通知方法。用法如下:
<aop:pointcut id="testPointcut"
expression="execution(* aop.test.TestBean.*(..))" />
<aop:after-returning pointcut-ref="testPointcut"
method="AfterReturnAdvice" returning="reVlue" />
</aop:aspect>
声明一个异常通知使用<aop:after-throwing />标签,它有一个类似于throwing属性又来指定该通知匹配的异常类型。用法如下:
<aop:pointcut id="testPointcut"
expression="execution(* aop.test.TestBean.*(..))" />
<aop:after-throwing pointcut-ref="testPointcut"
method="afterThrowingAdvice" throwing="throwable" />
</aop:aspect>
环绕通知是所有通知中功能最强大的通知,用<aop:around/>标签来声明。用法如下:
<aop:pointcut id="testPointcut"
expression="execution(* aop.test.TestBean.*(..))" />
<aop:around pointcut-ref="testPointcut" method="aroundAdvice"/>
</aop:aspect>
execution组合表达式表述数据库事务切点:
大部分service类的方法使用数据源txManager-datasourceone,对应事物切点txPointcut-datasourceone,事物拦截器txAdvice-datasourceone;
service层PublishService类的几个方法使用数据源txManager-datasourcetwo,对应事物切点txPointcut-datasourcetwo,事物拦截器txAdvice-datasourcetwo;
一个自定义方法拦截器RuntimeLogInterceptor(拦截每个方法,并记录每个方法的执行日志),拦截切点runtimeLogInterceptorPoint;
<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>
--------------------------------------------------------------------------------
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声明式配置
- Spring 2.x AOP声明式配置+声明式事务管理
- Spring 2.x AOP 配置方式整理
- 使用Spring AOP 自动代理配置声明式事务
- 使用Spring AOP 自动代理配置声明式事务
- Spring基于tx/aop声明式事务配置
- spring声明式事务配置方法 aop:config切入
- Spring AOP动态代理 /声明式事务管理与配置介绍
- Spring声明式事务配置——AOP方式
- Spring基于tx/aop声明式事务配置
- spring 2.x 声明式事务
- 使用Spring 2.x的声明事物配置方式
- 基于XML配置的纯POJO Spring 2.x Aop
- Spring Aop实现声明式事务
- Spring AOP声明式应用源码分析
- spring AOP事物管理(声明式事物)
- spring声明式事务【使用AOP】
- Spring aop实现声明式事务
- 阶段总结!
- linux下vi与vim编辑器的区别及使用方法
- Remoting基础(一)
- 《探索着传说》(The Sword of Truth改编) 偶喜欢的奇幻剧(小说) 简介
- 2010年计算机图书畅销榜——IT人文篇
- Spring 2.x AOP声明式配置
- DansGuardian
- Hadoop的sequence File
- squid + dansguardian + iptable 实现网页过滤
- 具有即时通讯(IM)功能的搜索引擎,只为云计算而生!
- in和exists的区别与SQL执行效率分析
- oracle datapump
- JDO 与 Hibernate
- “中兴杯”比赛