spring aop配置及用例说明(2)
欢迎交流转载:http://www.cnblogs.com/shizhongtao/p/3473362.html
这里先介绍下几个annotation的含义,
- @Before:表示在切入点之前执行。
- @AfterReturning:表示返回之后执行。
- @AfterThrowing:表示在切入点,如果抛出异常就执行这个方法。
- @After:表示在找到该方法执行后,它是在切入点方法返回前执行。通常用于释放资源。
接上篇介绍,在使用“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 typeSerializable
. -
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 }