Spring Aop 的使用
pointcut 点的语法
常用的
execution(modifiners-pattern?ret-type-pattern declaring-type-pattern? name-param(param-patterm)throws-pattern?)
? 表示:该参数可以出现一次或零次
中文: execution(<修饰符>?<返回类型> <声明类型>?<方法名>(<参数>)<异常>?)
举例:execution(* com.mine.springsourcestudy.aop.dao.AopDao.*(…))
目标拦截对象
@Repository
public class AopDao {
public String result() {
// if(true){
// throw new RuntimeException("test");
// }//会触发afterThrowing
return "aopDao";
}
}
切面的定义
@Component
@Aspect
@Order(1)//定义Aop的执行顺序
//执行顺序 around -> before(joinPoint.proceed()执行) ->afterReturning-> after(joinPoint.proceed()执行) -> around //No exception
//执行顺序 around -> before(joinPoint.proceed()执行) ->afterThrowing-> after(joinPoint.proceed()执行) -> around // exception,afterThrowing 执行后afterReturning不会执行
public class BaseAop {
@Pointcut("execution(* com.mine.springsourcestudy.aop.dao.AopDao.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void before(){
System.out.println("BaseAop before......");
}
@After("pointCut()")
public void after(){
System.out.println("BaseAop after......");
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) {
System.out.println("BaseAop around before......");
Object proceed=null;
try{
proceed = joinPoint.proceed();
}catch (Throwable e){
e.printStackTrace();
}
System.out.println("BaseAop around after......");
// if(proceed!=null){
// throw new RuntimeException("test");
// }这个会触发afterThrowing
return proceed;//不返回处理结果 则被代理的类执行结果就没了
}
@AfterReturning("pointCut()")
public void afterReturning(){
System.out.println("BaseAop afterReturning......");
}
@AfterThrowing("pointCut()")
public Object afterThrowing(){
System.out.println("BaseAop afterThrowing............");
return "dao";
}
}
@Aspect
@Component
@Order(2)
//多个切面的执行顺序 和注解切面
//aroundA->beforeA->aroundB->beforeB->afterReturnB->afterB->aroundB->afterReturnA->afterA->aroundA
//执行结果
// BaseAop around before......
//BaseAop before......
//LogAop around before........
//LogAop before........
//LogAop after........
//LogAop around after........
//BaseAop afterReturning......
//BaseAop after......
//BaseAop around after......
public class LogAop {
//对使用这个注解的进行拦截
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
public void annotationPointcut(){}
@Before("pointcut()")
public void before() {
System.out.println("LogAop before........");
}
@After("pointcut()")
public void after() {
System.out.println("LogAop after........");
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) {
System.out.println("LogAop around before........");
Object proceed=null;
try {
proceed = joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("LogAop around after........");
return proceed;
}
@Pointcut("execution(* com.mine.springsourcestudy.aop.dao.*.*(..))")
public void pointcut(){ }
@Before("annotationPointcut()")
public void beforeannotationPointcut() {
System.out.println("LogAop annotationPointcut........");
}
}
** 注意这里有个比较坑的地方 around 和 before after的执行顺序问题,具体注释里面有写,是经过测试的 基于Spring5 **