Spring的AOP可以通过对@AspectJ注解的支持和在XML中配置来实现,本文通过实例简述如何在Spring中使用AspectJ.
一:使用AspectJ注解:
1,启用对AspectJ的支持:
通过在Spring的配置中引入下列元素来启用Spring对AspectJ的支持:
<aop:aspectj-autoproxy />
或者(如果不是使用XSD的话)
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
2,声明一个带有@Aspect注解的类,在这个类中声明那些方法需要被'关注'(利用@Pointcut),在那些时机点进行关注(利用@Before,@AfterReturning等等...),执行'切入'的方法
3,在Spring的配置文件中定义这个'切面'类:任意带有一个@Aspect切面(拥有@Aspect注解)的bean都将被Spring自动识别并用于配置在Spring AOP.
4,使用被Spring管理的bean,在执行被'关注'的方法时,'切入'的方法就会被执行.
一个完整的例子:
需要被'切入'的类:
1 public class Monkey { 2 public void stealPeaches(String name) { 3 System.out.println(" Monkey " + name + " is stealling peaches..."); 4 } 5 6 public void stealCorns(String name) { 7 System.out.println(" Monkey " + name + " is stealling corns..."); 8 } 9 }
切面类
1 @Aspect
2 public class Guardian {
3 @Pointcut("execution(* com.test.spring.aspectj.Monkey.stealPeaches(..))")
4 public void guardOrchard() {
5 }
6
7 @Before(value = "guardOrchard()")
8 public void guardOrchardBefore() {
9 System.out.println("Guardian spotted a monkey is approaching the orchard...");
10 }
11
12 @AfterReturning("guardOrchard() && args(name,..)")
13 public void guardOrchardAfter(String name) {
14 System.out.println("Guardian caught a monkey stealling peaches whoes name is " + name + "...");
15 }
16 @Around("guardOrchard() && args(name,..)")
17 public void guardOrchardAround(ProceedingJoinPoint joinpoint,String name) {
18 System.out.println("Guardian guardOrchardAround started ... " + name);
19 try {
20 joinpoint.proceed();
21 } catch (Throwable e) {
22 System.out.println("Guardian guardOrchardAround exception happened ... " + name);
23 }
24 System.out.println("Guardian guardOrchardAround completed ... " + name);
25 }
26 @Pointcut("execution(* com.test.spring.aspectj.Monkey.stealCorns(..))")
27 public void guardFarm() {
28 }
29
30 @Before(value = "guardFarm()")
31 public void guardFarmBefore() {
32 System.out.println("Guardian spotted a monkey is approaching the farm...");
33 }
34
35 @AfterReturning("guardFarm() && args(name,..)")
36 public void guardFarmAfter(String name) {
37 System.out.println("Guardian caught a monkey stealling corns whoes name is " + name + "...");
38 }
39 }
配置文件
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
4 xsi:schemaLocation="
5 http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
7 http://www.springframework.org/schema/aop
8 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
9 <!--
10 <aop:aspectj-autoproxy /> equals to <bean
11 class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"
12 />
13 -->
14 <aop:aspectj-autoproxy />
15 <bean id="guardian" class="com.test.spring.aspectj.Guardian" />
16
17 <bean id="monkey" class="com.test.spring.aspectj.Monkey" />
18
19 </beans>
使用bean
1 ApplicationContext context = new ClassPathXmlApplicationContext("conf/aspectJAppcontext.xml");
2 Monkey monkey = (Monkey) context.getBean("monkey");
3 try {
4 monkey.stealPeaches("mighty monkey");
5 monkey.stealCorns("mighty monkey");
6 } catch (Exception e) {
7 }
运行结果
1 Guardian spotted a monkey is approaching the orchard...
2 Guardian guardOrchardAround started ... mighty monkey
3 Monkey mighty monkey is stealling peaches...
4 Guardian caught a monkey stealling peaches whoes name is mighty monkey...
5 Guardian guardOrchardAround completed ... mighty monkey
6 Guardian spotted a monkey is approaching the farm...
7 Monkey mighty monkey is stealling corns...
8 Guardian caught a monkey stealling corns whoes name is mighty monkey...
二:通过XML配置AspectJ实现AOP:在java类中定义要被'方面'调用的切入方法,在XML中配置.
例子:被'切入'的类,普通java类:
1 public class Monkey {
2 public void stealPeaches(String name) {
3 System.out.println(" Monkey " + name + " is stealling peaches...");
4 }
5
6 public void stealCorns(String name,int numberToSteal) {
7 System.out.println(" Monkey " + name + " is stealling corns...");
8 }
9 }
定义要被'方面'调用的切入方法的类:
1 public class XMLGuardian {
2 public void guardOrchardBefore() {
3 System.out.println("XMLGuardian spotted a monkey is approaching the orchard...");
4 }
5
6 public void guardOrchardAfter() {
7 System.out.println("XMLGuardian caught a monkey stealling peaches whoes name is ...");
8 }
9 public void guardFarmBefore() {
10 System.out.println("XMLGuardian spotted a monkey is approaching the farm...");
11 }
12 public void guardFarmAfter(String name,int num,Object retVal) {
13 System.out.println("XMLGuardian caught a monkey stealling " + num + " corns whoes name is ..." + name );
14 }
15 }
XML配置:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
4 xsi:schemaLocation="
5 http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
7 http://www.springframework.org/schema/aop
8 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
9
10 <bean id="guardian" class="com.test.spring.aspectj.XMLGuardian" />
11 <bean id="monkey" class="com.test.spring.aspectj.Monkey" />
12 <aop:config>
13
14 <aop:aspect id="myAspect" ref="guardian">
15 <aop:pointcut id="guardOrchard"
16 expression="execution(* com.test.spring.aspectj.Monkey.stealPeaches(..))" />
17
18 <aop:before pointcut-ref="guardOrchard" method="guardOrchardBefore" />
19 <aop:after-returning pointcut-ref="guardOrchard" method="guardOrchardAfter"/>
20
21 <aop:pointcut id="guardFarm"
22 expression="execution(* com.test.spring.aspectj.Monkey.stealCorns(..))" />
23
24 <aop:before pointcut-ref="guardFarm" method="guardFarmBefore" />
25 <aop:after-returning pointcut="execution(* com.test.spring.aspectj.Monkey.stealCorns(..)) and args(name,num,..)" returning="retVal"
26 method="guardFarmAfter" />
27 <!-- arg-names="name1" -->
28 </aop:aspect>
29 </aop:config>
30 </beans>
客户端测试代码:
1 ApplicationContext context = new ClassPathXmlApplicationContext("conf/xmlaspectJAppcontext.xml");
2 Monkey monkey = (Monkey) context.getBean("monkey");
3 try {
4 monkey.stealPeaches("mighty monkey");
5 monkey.stealCorns("mighty monkey",3);
6 } catch (Exception e) {
7 }
运行结果
1 XMLGuardian spotted a monkey is approaching the orchard...
2 Monkey mighty monkey is stealling peaches...
3 XMLGuardian caught a monkey stealling peaches whoes name is ...
4 XMLGuardian spotted a monkey is approaching the farm...
5 Monkey mighty monkey is stealling corns...
6 XMLGuardian caught a monkey stealling 3 corns whoes name is ...mighty monkey
Spring AOP 只支持对bean的方法级的'切入',而且AOP的内部机制和AspectJ有所区别,Spring主要是通过动态代理来实现AOP,使用JDK的动态代理(如果被代理的bean是interface的话)或者CGLIB(如果如果被代理的bean不是interface的话).
浙公网安备 33010602011771号