Spring AOP的概念这里不做叙述,自行百度。
AOP实现的三种方式:spring配置,注解,代理。
使用AOP需要依赖的jar除了spring需要的核心包之外还需要
可自行下载最新的jar包
1、Spring配置方式:
定义一个切入点类(Pointcut),所谓切入点类就是需要被切入执行通知(Advice)方法的业务类:
package com.ouyang.aop.test;
public class AopPointcut {
//业务代码
public String sayHello(String a,String b){
System.out.println("Helllllo Aop:"+a+"--"+b);
return "0";
}
}
定义一个通知类(Advice),即执行业务代码之前或之后需要执行类:
package com.ouyang.aop.test;
public class AopTestAdvice {
public void before(){
System.out.println("method before");
}
public void after(){
System.out.println("method after");
}
public void afterReturn(){
System.out.println("method for after return");
}
}
修改spring配置文件 applicationContext.xml,如果没有直接创建一个,修改里面的内容:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<!--spring注入通知类:AopTestAdvice-->
<bean id="aopTestAdvice" class="com.ouyang.aop.test.AopTestAdvice"/>
<!--spring注入切入点类:AopPointcut-->
<bean id="iAopPointcut" class="com.ouyang.aop.test.AopPointcut"/>
<!--AOP关键配置-->
<aop:config>
<!--配置切面,ref是指关联id为aopTestAdvice的bean,也就是上面配置的通知类-->
<aop:aspect id="aopAdvice" ref="aopTestAdvice">
<!--配置切入点,execution(* com.ouyang.aop.test.AopPointcut.*(..)),
括弧里面第一个*表示任意返回值, 后面接着是切入点类的所在包和类名:com.ouyang.aop.test->包名,AopPointcut->切入点类,
类名后面的.*指任意AopPointcut方法,(..)任意个数的方法参数。
比如说需要配com.ouyang.aop.test这个包里面的任何类的任何方法,可以:execution(* com.ouyang.aop.test.*.*(..))
再比如说 需要配AopPointcut这个切入点的say开头的方法,可以:execution(* com.ouyang.aop.test.AopPointcut.say*(..))。
id可以自定义,以便切入的时候引用
-->
<aop:pointcut id="addAllMethod" expression="execution(* com.ouyang.aop.test.AopPointcut.*(..)) " />
<!-- 配置切入后,执行业务代码之前要执行的方法,method:需要执行的方法名, pointcut-ref切点关联就是上面配置id -->
<aop:before method="before" pointcut-ref="addAllMethod" />
<!-- 配置切入后,执行完业务代码后要执行的方法,method:需要执行的方法名, pointcut-ref切点关联就是上面配置id -->
<aop:after method="after" pointcut-ref="addAllMethod" />
<!-- 配置切入后,执行完业务代码后要执行的方法,method:需要执行的方法名, pointcut-ref切点关联就是上面配置id,这个会再after之后执行 -->
<aop:after-returning method="afterReturn" pointcut-ref="addAllMethod" />
</aop:aspect>
</aop:config>
</beans>
最后写一个测试类:
package com.ouyang.aop.test;
public class AopTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
AopPointcut iAop = (AopPointcut)ctx.getBean("iAopPointcut");
iAop.sayHello("aaa","bbbb");
}
}
可以看到运行结果如下:
以上就是最简单的AOP配置,如果织入的方法需要知道被切入的业务代码的方法所带的参数和返回值,比如说
AopTestAdvice这个通知类的before方法需要知道被切入的sayHello方法所带的参数a,b分别是什么值,返回值又是什么?
则需要做以下两处修改:
1、修改spring配置文件AOP配置:
修改后的内容:
<aop:config>
<aop:aspect id="aopAdvice" ref="aopTestAdvice">
<aop:pointcut id="addAllMethod" expression="execution(* com.ouyang.aop.test.AopPointcut.*(..)) and args(arg1,arg2) " />
<aop:before method="before" pointcut-ref="addAllMethod" arg-names="arg1,arg2"/>
<aop:after method="after" pointcut-ref="addAllMethod" arg-names="arg1,arg2"/>
<aop:after-returning method="afterReturn" pointcut-ref="addAllMethod" returning="rvt" arg-names="rvt,arg1,arg2"/>
</aop:aspect>
</aop:config>
以上修改内容 修改了切入点为带两个参数的方法,arg-names为参数名称,returning为返回值
2、修改通知类AopTestAdvice的各个方法:
public void before(Object arg1,Object arg2){
System.out.println("method before:"+arg1+"--"+arg2);
}
public void after(Object arg1,Object arg2){
System.out.println("method after:"+arg1+"--"+arg2);
}
public void afterReturn(Object rvt,Object arg1,Object arg2){
System.out.println("method for after return:"+arg1+"---"+arg2+"----return value:"+rvt);
}
分别加上参数名称arg1,arg2,需要注意的是 afterReturn会多一个参数rvt,它表示返回值。
再次运行测试类时,这次看到结果为:
通知类里面的方法可以看到调用业务类sayHello方法时传入的参数为aaa,bbb,并且在 afterRetrun里面可以知道业务方法返回值是0.值得注意的是:spring配置的参数名必须和通知类里的各个方法的参数名一致,否则会报错,至于原因还不太明白,没有深究。。。
当然除了以上的before,after,afterReturn,还有after-throwing(抛出异常后通知),around(环绕通知,它包含前面所有节点,可单独使用),配置方式大同小异,这不作讲解。
至于AOP的用途,比如说写入日志,原来处理方法可能是在每个业务方法都需要写日志,但是通过AOP配置之后可以为每个业务方法切入统一写日志,省事很多,还有其他用途,大伙可自行百度。
以上就是AOP spring配置方式,由于时间关系,关于通过注解和代理方式配置AOP,请听下文分解。