Spring2.5注解实现AOP(转)

这个例子非常的简单,下面是实体类

Java代码
  1. package  test;  
  2.   
  3. /**  
  4.  *   
  5.  * @author neu_20063500  
  6.  *   
  7.  */   
  8. public   class  HelloWorld {  
  9.   
  10.  public   void  sayHello(String helloworld) {  
  11.   System.out.println(helloworld);  
  12.   throw   new  RuntimeException();  
  13.                 //这个异常是拿来测试,可有可无   
  14.  }  
  15. }  
package test;

/**
 * 
 * @author neu_20063500
 * 
 */
public class HelloWorld {

 public void sayHello(String helloworld) {
  System.out.println(helloworld);
  throw new RuntimeException();
                //这个异常是拿来测试,可有可无
 }
}

 

想使用AOP去处理这个sayHello方法

那么我们定义切面

 

Java代码
  1. package  test;     
  2.     
  3. import  org.aspectj.lang.ProceedingJoinPoint;     
  4. import  org.aspectj.lang.annotation.After;     
  5. import  org.aspectj.lang.annotation.AfterReturning;     
  6. import  org.aspectj.lang.annotation.AfterThrowing;     
  7. import  org.aspectj.lang.annotation.Around;     
  8. import  org.aspectj.lang.annotation.Aspect;     
  9. import  org.aspectj.lang.annotation.Before;     
  10. import  org.aspectj.lang.annotation.Pointcut;     
  11.     
  12. /**    
  13.  *     
  14.  * @author neu_20063500    
  15.  *     
  16.  */     
  17. @Aspect     
  18. public   class  AspectS {     
  19.     
  20.     // execution最常用,可以通过 & || !进行切入点表达式的连接      
  21.     // 可是是表达式,可以通过切入点标识重用表达式      
  22.     @Pointcut ( "execution(public void test.HelloWorld.sayHello(String))" )     
  23.     public   void  helloworld() {     
  24.     }     
  25.     
  26.     @Before ( "execution(public void test.HelloWorld.sayHello(String))" )     
  27.     public   void  beforeSayHello() {     
  28.         System.out.println("before sayHello" );     
  29.     }     
  30.     
  31.     @After ( "helloworld()" )     
  32.     public   void  afterSayHello() {     
  33.         System.out.println("after sayHello" );     
  34.     }     
  35.     
  36.     @AfterThrowing ( "test.AspectS.helloworld()" )     
  37.     public   void  exceptionSayHello() {     
  38.         System.out.println("throw runtime exception" );     
  39.     }     
  40.     
  41.     @AfterReturning ( "test.AspectS.helloworld()" )     
  42.     public   void  returnSayHello() {     
  43.         System.out.println("method has returned" );     
  44.     }     
  45.     
  46.     @Around ( "test.AspectS.helloworld()" )     
  47.     public  Object aroundSayHello(ProceedingJoinPoint pjp) {     
  48.         Object obj = null ;     
  49.         try  {     
  50.             System.out.println("around start" );     
  51.             obj = pjp.proceed();     
  52.             System.out.println("around end" );     
  53.         } catch  (Throwable e) {     
  54.             e.printStackTrace();     
  55.         }     
  56.         return  obj;     
  57.     }     
  58.          
  59.     /*    
  60.    
  61. 任意公共方法的执行:    
  62.    
  63. execution(public * *(..))    
  64. 任何一个以“set”开始的方法的执行:    
  65.    
  66. execution(* set*(..))    
  67. AccountService 接口的任意方法的执行:    
  68.    
  69. execution(* com.xyz.service.AccountService.*(..))    
  70. 定义在service包里的任意方法的执行:    
  71.    
  72. execution(* com.xyz.service.*.*(..))    
  73. 定义在service包或者子包里的任意方法的执行:    
  74.    
  75. execution(* com.xyz.service..*.*(..))    
  76. 在service包里的任意连接点(在Spring AOP中只是方法执行) :    
  77.    
  78. within(com.xyz.service.*)    
  79. 在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :    
  80.    
  81. within(com.xyz.service..*)    
  82. 实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执 行) :    
  83.    
  84. this(com.xyz.service.AccountService)    
  85. 'this'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知 体内访问到的部分。    
  86. 实现 了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :    
  87.    
  88. target(com.xyz.service.AccountService)    
  89. 'target'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在 通知体内访问到的部分。    
  90. 任何一个只接受 一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在Spring AOP中只是方法执行)     
  91.    
  92. args(java.io.Serializable)    
  93. 'args'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知 体内访问到的部分。    
  94. 请注意在例子中给出 的切入点不同于 execution(* *(java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的 (Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。    
  95.    
  96. 有一 个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)     
  97.    
  98. @target(org.springframework.transaction.annotation.Transactional)    
  99. '@target' 也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得 annotation对象可以在通知体内访问到的部分。    
  100. 任何一个目标对象声明的类型有一个 @Transactional 注解的连接点(在Spring AOP中只是方法执 行)    
  101.    
  102. @within(org.springframework.transaction.annotation.Transactional)    
  103. '@within'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得 annotation对象可以在通知体内访问到的部分。    
  104. 任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只 是方法执行)     
  105.    
  106. @annotation(org.springframework.transaction.annotation.Transactional)    
  107. '@annotation' 也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得 annotation对象可以在通知体内访问到的部分。    
  108. 任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点 (在Spring AOP中只是方法执行)     
  109.    
  110. @args(com.xyz.security.Classified)    
  111. '@args'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得 annotation对象可以在通知体内访问到的部分。    
  112.    
  113. */     
  114. }    
package test;   
  
import org.aspectj.lang.ProceedingJoinPoint;   
import org.aspectj.lang.annotation.After;   
import org.aspectj.lang.annotation.AfterReturning;   
import org.aspectj.lang.annotation.AfterThrowing;   
import org.aspectj.lang.annotation.Around;   
import org.aspectj.lang.annotation.Aspect;   
import org.aspectj.lang.annotation.Before;   
import org.aspectj.lang.annotation.Pointcut;   
  
/**  
 *   
 * @author neu_20063500  
 *   
 */  
@Aspect  
public class AspectS {   
  
    // execution最常用,可以通过 & || !进行切入点表达式的连接   
    // 可是是表达式,可以通过切入点标识重用表达式   
    @Pointcut("execution(public void test.HelloWorld.sayHello(String))")   
    public void helloworld() {   
    }   
  
    @Before("execution(public void test.HelloWorld.sayHello(String))")   
    public void beforeSayHello() {   
        System.out.println("before sayHello");   
    }   
  
    @After("helloworld()")   
    public void afterSayHello() {   
        System.out.println("after sayHello");   
    }   
  
    @AfterThrowing("test.AspectS.helloworld()")   
    public void exceptionSayHello() {   
        System.out.println("throw runtime exception");   
    }   
  
    @AfterReturning("test.AspectS.helloworld()")   
    public void returnSayHello() {   
        System.out.println("method has returned");   
    }   
  
    @Around("test.AspectS.helloworld()")   
    public Object aroundSayHello(ProceedingJoinPoint pjp) {   
        Object obj = null;   
        try {   
            System.out.println("around start");   
            obj = pjp.proceed();   
            System.out.println("around end");   
        } catch (Throwable e) {   
            e.printStackTrace();   
        }   
        return obj;   
    }   
       
    /*  
 
任意公共方法的执行:  
 
execution(public * *(..))  
任何一个以“set”开始的方法的执行:  
 
execution(* set*(..))  
AccountService 接口的任意方法的执行:  
 
execution(* com.xyz.service.AccountService.*(..))  
定义在service包里的任意方法的执行:  
 
execution(* com.xyz.service.*.*(..))  
定义在service包或者子包里的任意方法的执行:  
 
execution(* com.xyz.service..*.*(..))  
在service包里的任意连接点(在Spring AOP中只是方法执行) :  
 
within(com.xyz.service.*)  
在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :  
 
within(com.xyz.service..*)  
实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行) :  
 
this(com.xyz.service.AccountService)  
'this'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。  
实现了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :  
 
target(com.xyz.service.AccountService)  
'target'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在通知体内访问到的部分。  
任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在Spring AOP中只是方法执行)   
 
args(java.io.Serializable)  
'args'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知体内访问到的部分。  
请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的(Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。  
 
有一个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)   
 
@target(org.springframework.transaction.annotation.Transactional)  
'@target' 也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。  
任何一个目标对象声明的类型有一个 @Transactional 注解的连接点(在Spring AOP中只是方法执行)  
 
@within(org.springframework.transaction.annotation.Transactional)  
'@within'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。  
任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只是方法执行)   
 
@annotation(org.springframework.transaction.annotation.Transactional)  
'@annotation' 也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。  
任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点(在Spring AOP中只是方法执行)   
 
@args(com.xyz.security.Classified)  
'@args'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。  
 
*/  
}  

 

然后定义配置文件,注意将切面对象和实体对象交给Spring管理:

 

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:context = "http://www.springframework.org/schema/context"     
  4.     xmlns:aop = "http://www.springframework.org/schema/aop"   xmlns:tx = "http://www.springframework.org/schema/tx"     
  5.     xsi:schemaLocation ="        
  6.     http://www.springframework.org/schema/beans         
  7.     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd         
  8.     http://www.springframework.org/schema/context         
  9.     http://www.springframework.org/schema/context/spring-context-2.5.xsd        
  10.     http://www.springframework.org/schema/aop        
  11.     http://www.springframework.org/schema/aop/spring-aop-2.5.xsd        
  12.     http://www.springframework.org/schema/tx        
  13.     http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">      
  14.     < context:annotation-config   />      
  15.     < aop:aspectj-autoproxy   />      
  16.     < bean   id = "aspects"   class = "test.AspectS" > </ bean >      
  17.     < bean   id = "helloworld"   class = "test.HelloWorld" > </ bean >      
  18. </ beans >     
  19.    
<?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" xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="      
    http://www.springframework.org/schema/beans       
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd       
    http://www.springframework.org/schema/context       
    http://www.springframework.org/schema/context/spring-context-2.5.xsd      
    http://www.springframework.org/schema/aop      
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd      
    http://www.springframework.org/schema/tx      
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">   
    <context:annotation-config />   
    <aop:aspectj-autoproxy />   
    <bean id="aspects" class="test.AspectS"></bean>   
    <bean id="helloworld" class="test.HelloWorld"></bean>   
</beans>  
 

 

然后使用客户端调用:

 

Java代码
  1. package  test;     
  2.     
  3. import  org.springframework.context.ApplicationContext;     
  4. import  org.springframework.context.support.ClassPathXmlApplicationContext;     
  5.     
  6. public   class  Client {     
  7.     
  8.  public   static   void  main(String[] args) {     
  9.   ApplicationContext cx = new  ClassPathXmlApplicationContext(     
  10.     "applicationContext.xml" );     
  11.   HelloWorld bean = (HelloWorld)cx.getBean("helloworld" );     
  12.   bean.sayHello("hello world" );     
  13.  }     
  14. }   
package test;   
  
import org.springframework.context.ApplicationContext;   
import org.springframework.context.support.ClassPathXmlApplicationContext;   
  
public class Client {   
  
 public static void main(String[] args) {   
  ApplicationContext cx = new ClassPathXmlApplicationContext(   
    "applicationContext.xml");   
  HelloWorld bean = (HelloWorld)cx.getBean("helloworld");   
  bean.sayHello("hello world");   
 }   
} 

 

 

当sayHello没有抛出异常时,执行结果是:

 

Java代码
  1. before sayHello     
  2. around start     
  3. hello world     
  4. after sayHello     
  5. method has returned     
  6. around end    
before sayHello   
around start   
hello world   
after sayHello   
method has returned   
around end  

 

 

当sayHello执行抛出异常时候,执行结果是

 

Java代码
  1. around start     
  2. hello world     
  3. after sayHello     
  4. throw  runtime exception    
around start   
hello world   
after sayHello   
throw runtime exception  

 

 

给出一个比较典型和常用的切点:

Java代码
  1. package  test;     
  2.     
  3. import  org.aspectj.lang.annotation.Aspect;     
  4. import  org.aspectj.lang.annotation.Pointcut;     
  5.     
  6. @Aspect     
  7. public   class  SystemArchitecture {     
  8.     
  9.     /**    
  10.      * A join point is in the web layer if the method is defined in a type in    
  11.      * the com.xyz.someapp.web package or any sub-package under that.    
  12.      */     
  13.     @Pointcut ( "within(com.xyz.someapp.web..*)" )     
  14.     public   void  inWebLayer() {     
  15.     }     
  16.     
  17.     /**    
  18.      * A join point is in the service layer if the method is defined in a type    
  19.      * in the com.xyz.someapp.service package or any sub-package under that.    
  20.      */     
  21.     @Pointcut ( "within(com.xyz.someapp.service..*)" )     
  22.     public   void  inServiceLayer() {     
  23.     }     
  24.     
  25.     /**    
  26.      * A join point is in the data access layer if the method is defined in a    
  27.      * type in the com.xyz.someapp.dao package or any sub-package under that.    
  28.      */     
  29.     @Pointcut ( "within(com.xyz.someapp.dao..*)" )     
  30.     public   void  inDataAccessLayer() {     
  31.     }     
  32.     
  33.     /**    
  34.      * A business service is the execution of any method defined on a service    
  35.      * interface. This definition assumes that interfaces are placed in the    
  36.      * "service" package, and that implementation types are in sub-packages.    
  37.      *     
  38.      * If you group service interfaces by functional area (for example, in    
  39.      * packages com.xyz.someapp.abc.service and com.xyz.def.service) then the    
  40.      * pointcut expression "execution(* com.xyz.someapp..service.*.*(..))" could    
  41.      * be used instead.    
  42.      */     
  43.     @Pointcut ( "execution(* com.xyz.someapp.service.*.*(..))" )     
  44.     public   void  businessService() {     
  45.     }     
  46.     
  47.     /**    
  48.      * A data access operation is the execution of any method defined on a dao    
  49.      * interface. This definition assumes that interfaces are placed in the    
  50.      * "dao" package, and that implementation types are in sub-packages.    
  51.      */     
  52.     @Pointcut ( "execution(* com.xyz.someapp.dao.*.*(..))" )     
  53.     public   void  dataAccessOperation() {     
  54.     }     
  55. }    
  56.   
  57.  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值