SpringAOP之AspectJ+拦截自定义注解

一、AOP基本概念

假设现在我们要对一个Test类进行事务代码织入,那么我们需要知道这个类有哪些方法,然后需要知道这个类的哪些方法需要织入事务代码。

1.目标类:需要织入日志代码的类,也就是Test类。

2.连接点:目标类的所有方法,都叫做连接点。

3.切点:切点就是具体织入日志代码的方法。

4.增强:织入的日志代码,就是增强部分。

5.织入:将增强和目标类的切点方法结合在一起,形成一个新的方法。

6.代理:持有织入后新的方法的类。

7.切面:包含切点的定义,连接点的定义,增强的定义。比如,日志切面,将Test类的add()方法定义为切点,日志代码定义为增强。性能监视切面,将Test类的add()方法定义为切点,性能监视代码定义为增强。

二、SpringBoot的简单实例

@Aspect
@Component
public class AspectJPOJO {
    //在Springboot当中,直接定义一个切点就可以了,使用Component注解将切面纳入IOC容器管理,Spring会自动在调用目标类的时候,对切点进行拦截
    @Before(value = "execution (* com.study.service.*.*(..))")
    public void before(){
        System.out.println("织入前");
    }
}

使用SpringAOP的前提是,在项目中引入aspectjweaver包。上面的execution表示一个函数,第一个*表示返回值任意,第二个*表示service包下的任意类,第三个*表示任意方法,..表示参数为任意数量。Before注解的含义是在目标类的方法前添加增强。

三、不同增强类型

@Before:前置增强,织入在切点前面。

@AfterReturningAdvice:后置增强,织入在切点后面。可以使用returning属性将目标对象方法的返回值绑定给增强方法。如果目标方法抛异常,那么不会执行。

@AfterReturning(value = "execution (* com.study.service.*.*(..))",returning = "result")
    public void afterReturning(Object result){
        System.out.println("织入后" + result.toString());
    }

@After:后置增强,织入在切点后面,无论目标方法是否抛异常,都会执行。

@After(value = "execution (* com.study.service.*.*(..))")
    public void after(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName + "织入后");
    }

@Around:环绕增强。一定要传入ProceedingJoinPoint类,调用joinPoint.proceed()方法相当于调用目标类的方法。

@Around(value = "logAnnotation()")
    public void around(ProceedingJoinPoint joinPoint){
        System.out.println("around前");
        try {
            joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("around后");
    }

@AfterThrowing:后置增强,将抛出的异常绑定到增强方法。

@AfterThrowing(value = "execution (* com.study.service.*.*(..))",throwing = "e")
    public void afterThrowing(Exception e){
        System.out.println(e.getMessage());
    }

如@After后的代码所示,我们每个增强都可以传入一个JoinPoint类,通过该类可以获取切点的信息。

四、SpringAOP+自定义注解

注解类·

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnotation {
    String value() default "!23";
}

切面方法

@Before(value = "@annotation(com.study.aspectj.LogAnnotation)")
    public void beforeAnnotation(){
        System.out.println("注解织入前");
    }

因为@Before等等的增强方法后面配的都是切点,所以也可使用下面的配置方式

@Before(value = "logAnnotation()")
    public void beforeAnnotationPointcut(){
        System.out.println("注解切点织入前");
    }
@Pointcut(value = "@annotation(com.study.aspectj.LogAnnotation)")
    public void logAnnotation(){}

配置好之后只需要在业务逻辑上加上我们的自定义注解@LogAnnotation就可以了,SpringAOP会自动对纳入IOC容器的类里面的添加了@LogAnnotation注解的方法进行拦截,然后动态代理将代码织入到里面,默认使用JDK动态代理,如果不能使用JDK动态代理的情况,则会使用CGLib动态代理。

另外,如果针对不同的方法,我们进行不同的处理,需要获取自定义注解的信息,可以使用下面的代码

@Before(value = "logAnnotation()")
    public void beforeAnnotationPointcut(JoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
        System.out.println(annotation.value());
    }

输出结果是我们的默认值,!23。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值