使用Aspect快速实现一个自定义注解

最近写东西觉得将示例放前面比较好。

代码前置

重点:

  1. 切面类使用@Configuration, @Aspect注解
  2. 切面类主要方法使用@Before, @After, @AfterReturning, @AfterThrowing, @Around等做切入
  3. 使用的类需要使用@Resource方法注入才会生效。
@Aspect
@Configuration  
public class PrintBeforeMethodAspect {  
    @Around("@annotation(PrintBeforeMethod)")  
    public void printBefore(ProceedingJoinPoint joinPoint) throws Throwable {  
        System.out.println("before method");  
        joinPoint.proceed();  
        System.out.println("after method");  
    }  
}
复制代码
@Resource  
Test testService;

@RequestMapping("/aspect/test")  
public Object aspectTest() {  
    testService.test();  
    return "执行完毕";  
}
复制代码

起因

最近有个需要,需要给系统增加多租户功能,需要用到切面编程,使用到@Aspect, 分享一下

@Aspect介绍

@Aspect注解用于标注一个类为切面类。切面类是用来实现AOP(Aspect Oriented Programming)的重要组成部分。

@Aspect注解会告诉Spring框架,这个类包含切面逻辑,需要进行AOP处理。在注解的类中,可以定义切面方法,实现对其他方法的拦截和增强。

常用的切面方法有:

  1. @Before - 在目标方法执行前执行的方法,属于前置增强。
  2. @After - 在目标方法执行后执行的方法,属于后置增强。
  3. @AfterReturning -在目标方法正常完成后执行的方法,属于返回增强。
  4. @AfterThrowing - 在目标方法出现异常后执行的方法,属于异常增强。
  5. @Around - 可以在目标方法前后执行自定义的方法,实现织入增强。 可以有参数JoinPoint,用于获知织入点的方法签名等信息。

@Aspect注解的使用使得AOP可以针对业务层中的各个方法进行权限控制,性能监控,事务处理等操作,从而提高了系统的层次性和健壮性。

完整的实现样例

我是搭配注解来使用的

自定义注解

package com.kevinq.aspect;  
  
import java.lang.annotation.*;  
  
/**  
 * @author qww  
 * 2023/4/15 11:24 */
@Target({ElementType.METHOD})  
@Retention(RetentionPolicy.RUNTIME)  
@Inherited  
public @interface PrintBeforeMethod {  
  
  
}
复制代码

切面,主要程序:(注意,切面类上带有@Configuration 注解)

package com.kevinq.aspect;  
  
//import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.annotation.Around;  
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Before;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.stereotype.Component;  
  
/**  
 * @author qww  
 * 2023/4/15 11:27 */
@Aspect  
@Configuration  
public class PrintBeforeMethodAspect {  
  
    @Around("@annotation(PrintBeforeMethod)")  
    public void printBefore(ProceedingJoinPoint joinPoint) throws Throwable {  
        System.out.println("before method");  
        joinPoint.proceed();  
        System.out.println("after method");  
    }  
  
}
复制代码

调用方式:

增加注解

@Service  
public class TestService implements Test{  
  
    @Override  
    @PrintBeforeMethod    
    public void test() {  
        System.out.println("执行test方法");  
    }  
}
复制代码

调用方法

@Resource  
Test testService;

@RequestMapping("/aspect/test")  
public Object aspectTest() {  
    testService.test();  
    return "执行完毕";  
}
复制代码

值得注意的是,因为使用的@Configuration来注入,所以需要使用@Resource这种方法来实例化调用,用new TestService()无效。

猜你喜欢

转载自juejin.im/post/7222152731946139707