1、Spring除了XML中支持Schema方式配置AOP,还支持注解方式:使用@Aspect来配置
2、Spring默认不支持@Aspect风格的切面声明,通过如下配置开启@Aspect支持:
Java代码
<aop:aspectj-autoproxy/>
3、通过以上配置,Spring就能发现用@Aspect注解的切面内并把它应用到目标对象上。
4、定义一个切面:
@Aspect public class AspectStyle { @Before("execution(* com.sxit..*.*(..))") public void before(){ System.out.println("方法执行前执行....."); } }
5、后置返回通知:
@AfterReturning("execution(* com.sxit..*.*(..))") public void afterReturning(){ System.out.println("方法执行完执行....."); }
6、后置异常通知:
@AfterThrowing("execution(* com.sxit..*.*(..))") public void throwss(){ System.out.println("方法异常时执行....."); }
7、后置最终通知:
@After("execution(* com.sxit..*.*(..))") public void after(){ System.out.println("方法最后执行....."); }
8、环绕通知:
@Around("execution(* com.sxit..*.*(..))") public Object around(ProceedingJoinPoint pjp){ System.out.println("方法环绕start....."); try { pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("方法环绕end....."); }
9、按上面的每一个通知都要写一个定义,其实这部分可以抽出来,定义个一个公共的切入点。
package com.sxit; 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; @Aspect public class AspectStyle { @Pointcut("execution(* com.sxit..*.*(..))") public void init(){ } @Before(value="init()") public void before(){ System.out.println("方法执行前执行....."); } @AfterReturning(value="init()") public void afterReturning(){ System.out.println("方法执行完执行....."); } @AfterThrowing(value="init()") public void throwss(){ System.out.println("方法异常时执行....."); } @After(value="init()") public void after(){ System.out.println("方法最后执行....."); } @Around(value="init()") public Object around(ProceedingJoinPoint pjp){ System.out.println("方法环绕start....."); Object o = null; try { o = pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("方法环绕end....."); return o; } }
10、打印信息:
方法before前执行.....
方法环绕start.....
我看.....................
方法after执行.....
方法环绕end.....
方法afterReurning执行.....
参考自:http://jinnianshilongnian.iteye.com/blog/1418598
http://ch-space.iteye.com/blog/493956
示例:
一些常见的切入点的例子
execution(public * * (. .)) 任意公共方法被执行时,执行切入点函数。
execution( * set* (. .)) 任何以一个“set”开始的方法被执行时,执行切入点函数。
execution( * com.demo.service.AccountService.* (. .)) 当接口AccountService 中的任意方法被执行时,执行切入点函数。
execution( * com.demo.service.. (. .)) 当service 包中的任意方法被执行时,执行切入点函数。 within(com.demo.service.)在service 包里的任意连接点。 within(com.demo.service. .) 在service 包或子包的任意连接点。
this(com.demo.service.AccountService) 实现了AccountService 接口的代理对象的任意连接点。
target(com.demo.service.AccountService) 实现了AccountService 接口的目标对象的任意连接点。
args(java.io.Serializable) 任何一个只接受一个参数,且在运行时传入参数实现了 Serializable 接口的连接点
介绍:
@Before:方法前执行
@AfterReturning:运行方法后执行
@AfterThrowing:Throw后执行
@After:无论方法以何种方式结束,都会执行(类似于finally)
@Around:环绕执行