使用aop实现自定义注解的业务逻辑

一、引入aop依赖

 <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

二、新建一个注解类

package com.example.demo.infra.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author 郑稳振
 * @description: TODO
 * @date 2021/11/26 11:17
 */
@Target(value= {ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Token {

}

Java除了内置了三种标准注解,还有四种元注解。

@Target 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括:

 ElemenetType.CONSTRUCTOR 		构造器声明 
 ElemenetType.FIELD				域声明(包括 enum 实例) 
 ElemenetType.LOCAL_VARIABLE 	局部变量声明 
 ElemenetType.METHOD  			方法声明 
 ElemenetType.PACKAGE 			包声明 
 ElemenetType.PARAMETER 		参数声明 
 ElemenetType.TYPE				类,接口(包括注解类型)或enum声明 

@Retention 表示在什么级别保存该注解信息。可选的参数值在枚举类型 RetentionPolicy 中,包括:

 RetentionPolicy.SOURCE			注解将被编译器丢弃 
 RetentionPolicy.CLASS			注解在class文件中可用,但会被VM丢弃 
 RetentionPolicy.RUNTIME		VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

@Documented 将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与@see,@param 等。

@Inherited 允许子类继承父类中的注解。

三、新建一个切面类

在这里面可以实现注解的业务逻辑、比如权限校验等。

package com.example.demo.infra.Aspect;

import com.example.demo.infra.CommonException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
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;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

/**
 * @author 郑稳振
 * @description: TODO
 * @date 2021/11/26 11:23
 */
@Aspect
@Component
public class MyAspect {

    public static final Logger logger = LoggerFactory.getLogger(MyAspect.class);

    public static final String TOKEN_KEY = "token";
    
    @Pointcut("@annotation(com.example.demo.infra.annotations.Token)")
    public void annotationPointcut() {
    }

    @Before("annotationPointcut()")
    public void beforePointcut(JoinPoint joinPoint) {
    }

    @Around("@annotation(com.example.demo.infra.annotations.Token)")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        logger.info("进入方法之前");
        // 获取参数名称
        String[] params = methodSignature.getParameterNames();
        // 获取参数值
        Object[] args = joinPoint.getArgs();
        // 此处进入到方法前  可以实现一些业务逻辑
        for(String s:params){
            logger.info("params------------>{}",s);
        }
        for(Object object:args){
            logger.info("object------------>{}",object);
        }
        try{
            if(params.length!=0){
                throw new CommonException("异常");
            }

            Object object = joinPoint.proceed();//执行方法,可以对传入参数进行修改

        }catch (Exception e){
            logger.info("{}",e.toString());
        }

        //logger.info("返回结果---》{}",object);
        return ResponseEntity.ok("aop success!");//修改返回结果
    }

    /**
     * 在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
     * @param joinPoint
     */
    @AfterReturning("annotationPointcut()")
    public void doAfterReturning(JoinPoint joinPoint) {

        logger.info("进入方法之后");
    }

    @AfterThrowing("annotationPointcut()")
    private void afterThrowing() {
        logger.info("抛异常了。。。。。");
    }

}

四、测试controller

package com.example.demo.controller;

import com.example.demo.infra.annotations.Token;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; 
/**
 *@description: todo
 *@author:郑稳振
 *@Date : 2021/11/26:11:00
 */
@RestController
public class EasyExcelController {

    @RequestMapping("/ano")
    @Token
    public ResponseEntity<String> login(String name, String pwd){
        return ResponseEntity.ok("success!");
    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值