自定义注解的方式实现自定义切面类
参考
参考文献:
源代码及文章:https://www.cnblogs.com/hhhshct/p/8428045.html
自定义注解参考文章:https://blog.youkuaiyun.com/cool_summer_moon/article/details/80596510?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.nonecase
实现思路
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.自定义注解,需要增强的目标方法上加注解即可实现增强
/**
*自定义注解
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
}
3.配置切面类
3.1 类上注解
@Component // 将此类对象交给spring容器管理
@Scope // 默认 singleton 单例,全局一个
@Aspect // 声明当前类为切面类
public class AccessLimitAop {...}
3.2 切面类中添加一个无返回值的方法作为切入点,方法上加上@Pointcunt注解用于增强某些方法
//@Pointcut 注解的三种实现方式
//@Pointcut用来配置切入点,该方法无方法体,主要为方便同类中其他方法使用此处配置的切入点
@Pointcut("execution(public * com.example.demo.controller.HelloController.add*(..))")
public void addAdvice(){}
@Pointcut("execution(public * com.example.demo.controller.HelloController.add*(..)) && @annotation(com.example.demo.controller.MyAnnotation)" )
public void addAdvice(){}
@Pointcut(" @annotation(com.example.demo.controller.MyAnnotation)" )
public void addAdvice(){}
// execution 用与直接指定某个(些)包下的某某方法此处为add开头的方法进行增强
// annotation 用于引入自定义包下的注解
3.3 核心:添加核心方法,即对目标方法的增强方法使用@Around注解进行环绕增强,返回值类型封装为Object 类型
/** 单独使用
* 调用controller包下的任意类的任意方法时均会调用此方法
*/
@Around("execution(* com.company.controller.*.*(..))")
/**
*配合@Pointcut使用
*/
@Pointcut("execution(* com.company.controller.*.*(..))")
public void pointCut2() {}
@Around("pointCut2()")
增强方法实例
@Around("addAdvice()")
public Object Interceptor(ProceedingJoinPoint pjp){
Object result = null;
Object[] args = pjp.getArgs();
if(args != null && args.length >0) {
String deviceId = (String) args[0];
if(!"03".equals(deviceId)) {
return "no anthorization";
}
}
try {
result =pjp.proceed();// 这一步相当于执行了目标方法,此步之前相当于前置增强,之后如果还有方法相当于后置增强
} catch (Throwable e) {
e.printStackTrace();
}
return result;// 注意返回值必须要有,否则原目标方法的返回值就成了null
}
具体使用
@RestController
public class HelloController {
@MyAnnotation // 引入增强方法
@RequestMapping("/add1")
public String addData1(String deviceId) {
return "success";
}
总结
1.自定义切面可以用于登录,权限拦截用户限流等诸多场景使用时在@Pointcut 注解或@Around注解中通过切入点表达式的形式即可对目标方法进行增强
2.为了提高灵活性可以引入自定义注解,使用自定义注解的好处是在我们需要引入切面时直接在目标类,方法或属性上添加自定义注解即可引入
3.使用前理解AOP 的相关注解和自定义注解的元注解可以加深对本文的理解,本文只是我自学后的一点心得体会代码具体实现大家可以去尝试一下