欢迎交流转载:http://www.cnblogs.com/shizhongtao/p/3473362.html
这里先介绍下几个annotation的含义,
接上篇介绍,在使用“AfterReturning建议”时候,如果想要得到返回参数可以这样写:其中retVal是代表返回的参数对象。我这里直接打印出来了toString方法。
1 @AfterReturning(pointcut="execution(public * com.bing.test..*.*(..))",returning="retVal") 2 public void afterReturning(Object retVal) { 3 if(retVal!=null) 4 System.out.println("参数是:"+retVal); 5 System.out.println("afterReturning Method"); 6 }
同样,如果你希望对方法抛出的异常进行处理的话你也可以去捕获。spring声明式事务管理就是这个原理。
1 import org.aspectj.lang.annotation.Aspect; 2 import org.aspectj.lang.annotation.AfterThrowing; 3 4 @Aspect 5 public class AfterThrowingExample { 6 7 @AfterThrowing( 8 pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()", 9 throwing="ex") 10 public void doRecoveryActions(DataAccessException ex) { 11 // ... 12 } 13 14 }
关于pointcut表达式说明:
the execution of any public method:匹配所有public的方法
execution(public * *(..))
the execution of any method with a name beginning with "set":匹配一set开头的所有方法
execution(* set*(..))
the execution of any method defined by the AccountService
interface:匹配类com.xyz.service.AccountService下所有方法
execution(* com.xyz.service.AccountService.*(..))
the execution of any method defined in the service package:匹配com.xyz.service包下的所有类的方法,不包含子包
execution(* com.xyz.service.*.*(..))
the execution of any method defined in the service package or a sub-package:匹配com.xyz.service包以及子包下的所有类的方法,包含子包
execution(* com.xyz.service..*.*(..))
any join point (method execution only in Spring AOP) within the service package:匹配在com.xyz.service包下类的所有方法
within(com.xyz.service.*)
any join point (method execution only in Spring AOP) within the service package or a sub-package:
within(com.xyz.service..*)
any join point (method execution only in Spring AOP) where the proxy implements the AccountService
interface:实现AccountService
接口的所有类
this(com.xyz.service.AccountService)
'this' is more commonly used in a binding form :- see the following section on advice for how to make the proxy object available in the advice body.
any join point (method execution only in Spring AOP) where the target object implements the AccountService
interface:
target(com.xyz.service.AccountService)
'target' is more commonly used in a binding form :- see the following section on advice for how to make the target object available in the advice body.
any join point (method execution only in Spring AOP) which takes a single parameter, and where the argument passed at runtime is Serializable
:
args(java.io.Serializable)
'args' is more commonly used in a binding form :- see the following section on advice for how to make the method arguments available in the advice body.
Note that the pointcut given in this example is different to execution(* *(java.io.Serializable))
: the args version matches if the argument passed at runtime is Serializable, the execution version matches if the method signature declares a single parameter of type Serializable
.
any join point (method execution only in Spring AOP) where the target object has an @Transactional
annotation:
@target(org.springframework.transaction.annotation.Transactional)
'@target' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.
any join point (method execution only in Spring AOP) where the declared type of the target object has an @Transactional
annotation:
@within(org.springframework.transaction.annotation.Transactional)
'@within' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.
any join point (method execution only in Spring AOP) where the executing method has an @Transactional
annotation:
@annotation(org.springframework.transaction.annotation.Transactional)
'@annotation' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.
any join point (method execution only in Spring AOP) which takes a single parameter, and where the runtime type of the argument passed has the @Classified
annotation:
@args(com.xyz.security.Classified)
'@args' can also be used in a binding form :- see the following section on advice for how to make the annotation object(s) available in the advice body.
any join point (method execution only in Spring AOP) on a Spring bean named 'tradeService
':
bean(tradeService)
any join point (method execution only in Spring AOP) on Spring beans having names that match the wildcard expression '*Service
':
bean(*Service)
这里贴上我用于测试的代码:
manager类,相当于service层
1 package com.bing.test; 2 3 import org.springframework.beans.factory.annotation.Value; 4 import org.springframework.stereotype.Component; 5 6 @Component("manager") 7 public class Manager { 8 @Value("${user.name}") 9 private String myName; 10 @Value("${user.description}") 11 private String description; 12 13 public void sayHello() { 14 System.out.println("Hello " + myName); 15 } 16 17 public void getDes() { 18 System.out.println(description); 19 20 } 21 public String getName(){ 22 System.out.println("执行getName"); 23 return myName; 24 } 25 public String throwTest() throws Exception { 26 if (true) { 27 28 throw new Exception("new throwing test!"); 29 } 30 return "sdf"; 31 } 32 }
切面类:
1 package com.bing.test; 2 3 import org.aspectj.lang.annotation.After; 4 import org.aspectj.lang.annotation.AfterReturning; 5 import org.aspectj.lang.annotation.AfterThrowing; 6 import org.aspectj.lang.annotation.Aspect; 7 import org.aspectj.lang.annotation.Before; 8 import org.aspectj.lang.annotation.Pointcut; 9 import org.springframework.stereotype.Component; 10 11 @Aspect 12 // 定义切面类 13 @Component 14 // 把类装载到容器,与@service等作用一样 15 public class NotVeryUsefulAspect { 16 //配置切入点集合,这样在下面可以直接引入 17 @Pointcut("execution(public * com.bing.test..*.sayHello(..))") 18 public void inManager() {} 19 @Pointcut("within(com.bing.test..*)") 20 public void excutionManager() {} 21 // 表示在方法前面执行 22 @Before("com.bing.test.NotVeryUsefulAspect.inManager()") 23 public void before() { 24 25 System.out.println("before Method"); 26 } 27 @AfterReturning(pointcut="execution(public * com.bing.test..*.*(..))",returning="retVal") 28 public void afterReturning(Object retVal) { 29 if(retVal!=null) 30 System.out.println("参数是:"+retVal); 31 System.out.println("afterReturning Method"); 32 } 33 //@After("execution(public * com.bing.test..*.*(..))") 34 @After("within(com.bing.test.Manager)") 35 public void after() { 36 37 System.out.println("after Method"); 38 } 39 @AfterThrowing(pointcut="execution(* com.bing.test.*.throwTest(..))",throwing="ex") 40 public void afterThrow(Exception ex){ 41 42 System.out.println(ex.getMessage()); 43 44 System.out.println("AfterThrowing Method!"); 45 } 46 }
junit测试类:
1 package com.bing.jtest; 2 3 import javax.annotation.Resource; 4 5 import org.junit.Test; 6 import org.junit.runner.RunWith; 7 import org.springframework.test.context.ContextConfiguration; 8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 9 10 import com.bing.test.Manager; 11 12 @ContextConfiguration(locations = { "classpath:applicationContext.xml" }) 13 @RunWith(SpringJUnit4ClassRunner.class) 14 public class Testr { 15 16 @Resource(name="manager") 17 private Manager manager; 18 19 @Test 20 public void test() { 21 manager.sayHello(); 22 //manager.getDes(); 23 } 24 @Test 25 public void TestAfterReturning(){ 26 27 manager.getName(); 28 } 29 @Test 30 public void TestAfterThrow(){ 31 32 33 try { 34 manager.throwTest(); 35 } catch (Exception e) { 36 // TODO Auto-generated catch block 37 e.printStackTrace(); 38 } 39 40 } 41 }