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的话).