springboot自定义注解及获取注解值

注:网上搜集的内容,忘记留下出处,见谅

自定义注解

@Target(ElementType.METHOD)   //定义是用在方法上
@Retention(RetentionPolicy.RUNTIME)  // 定义是在运行时生效
public @interface ZlTest {
    String param() default "";       //定义参数,默认为空
}

获取值

  • 主要是方法参数多加一个注解类型的参数
/**
 * 定义一个切面,用于统计指定注解的方法调用时间
 *
 * @author zl
 * @ProjectName: MapDemo
 * @create 2018-12-13 10:08
 * @Version: 1.0
 * <p>Copyright: Copyright (zl) 2018</p>
 **/
@Component
@Aspect
@Slf4j
public class ZlAspect {

    @Around("serviceStatistics(zlTest)")
    public Object doAround(ProceedingJoinPoint joinPoint, ZlTest zlTest) throws Throwable {
        System.out.println("beginning----");
        /**
         * 获取方法参数值
         */
        String key = getKey(zlTest.param(), joinPoint);
        log.info("参数是:{}",key);

        /**
         * 运行doSth(),执行方法的具体业务,并获取返回值,用一个Object类型来接收
         */
        Object object = joinPoint.proceed();

        /**
         * 该方法的后置增强,可以修改返回值
         */
        object = 10;
        return object;
    }

再来一个例子

@Documented//说明该注解将被包含在javadoc中
//@Retention: 定义注解的保留策略,
@Retention(RUNTIME)// 注解会在class字节码文件中存在,在运行时可以通过反射获取到
//@Target:定义注解的作用目标
@Target({METHOD,PARAMETER})// 方法和方法参数
@Inherited//说明子类可以继承父类中的该注解
public @interface LogAnnotation {
    /**
    * 如果注解只有一个属性,那么肯定是赋值给该属性。
     * 如果注解有多个属性,而且前提是这多个属性都有默认值,那么你不写注解名赋值,会赋值给名字为“value”这属性。
     * 如果注解有多个属性,其中有没有设置默认值的属性,那么当你不写属性名进行赋值的时候,是会报错的。
     */
     //@AliasFor("")起别名
    int value() default 000;
}
 @Around(value = "LogAnnotation() && webLog() && @annotation(logAnnotation)")//环绕切点,在进入切点前,跟切点后执行
    public Object  doAround(ProceedingJoinPoint pjp, LogAnnotation logAnnotation)throws Throwable {
        Object result = null;
//        System.out.println("环绕。。。。。。1"+logAnnotation.value());
 
        //接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
 
        // 记录下请求内容
        logger.info("URI : " + request.getRequestURI());
        logger.info("URL : " + request.getRequestURL());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        logger.info("CLASS_METHOD : " + pjp.getSignature().getDeclaringTypeName() + "_" + pjp.getSignature().getName());
        logger.info("ARGS : " + Arrays.toString(pjp.getArgs()));
        System.out.println("ARGS对象:" + pjp.getArgs()[0]);
    }

详细介绍

import java.lang.annotation.*;
 
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestAnnotation {
    String value();   // 允许注解有参数
}
import com.great.annotation.TestAnnotation;
import com.great.annotation.TestAnnotation;
//import javassist.bytecode.SignatureAttribute;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
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.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
 
import java.lang.reflect.Method;
 
@Aspect // FOR AOP
@Order(-99) // 控制多个Aspect的执行顺序,越小越先执行, 当然也可以不写这注解, 对于写和不写@order的两个切面, 有@order的优先于无@order的执行; 都有@order时, 越小越执先执行
@Component
public class TestAspect {
 
    // @Before可以有两者写法, @annotation(形参test)
    @Before("@annotation(test)")
// 拦截被TestAnnotation注解的方法;如果你需要拦截指定package指定规则名称的方法,可以使用表达式execution(...),具体百度一下资料一大堆
// 因为参数传入了TestAnnotation ,所以会自动拦截@TestAnnotation 注解的
    public void beforeTest(JoinPoint point, TestAnnotation test) throws Throwable {
        System.out.println("beforeTest:" + test.name());   // 直接获取注解参数
    }
 
    @After("@annotation(test)")
    public void afterTest(JoinPoint point, TestAnnotation test) {
        System.out.println("afterTest:" + test.name());  // 直接获取注解参数
    }
 
    // 可以控制方法运行, 修改入参和返回值
    @Around("@annotation(test)")   // test表示aroundTest方法中的test入参
    public Object aroundTest(ProceedingJoinPoint pjp, TestAnnotation test) throws Throwable {
        System.out.println("afterTest:" + mq.value());
        // 获取入参并修改
        Object[] args = pjp.getArgs();
        args[0] = "";
        // 传入修改后的参数, 并继续执行
        Object res = pjp.proceed(args);
        // 修改返回值
        return res.toString() + res.toString();
    }
 
 
/* 
   // 指定切面
   @Pointcut("@annotation(com.great.annotation.TestAnnotation)")
    public void annotationPointCut() {
    }
   // @Before可以有两者写法, @annotation(函数名annotationPointCut)
   @Before("annotationPointCut()")
    public void before(JoinPoint joinPoint) {
        MethodSignature sign = (MethodSignature) joinPoint.getSignature();
        Method method = sign.getMethod();
        TestAnnotation annotation = method.getAnnotation(TestAnnotation.class);   // 获取指定注解实例
        System.out.println("打印:" + annotation.value() + " 前置日志1");   // 获取注解实例的参数
    }
    @After("annotationPointCut()")
    public void afterTTT(JoinPoint point) {
        MethodSignature sign = (MethodSignature) point.getSignature();
        Method method = sign.getMethod();
        TestAnnotation annotation = method.getAnnotation(TestAnnotation.class);  // 获取指定注解实例
        System.out.println("打印自带参数:" + annotation.value() + " 后置日志1");  // 获取注解实例的参数
    }
*/
 
}
@Around("@annotation(com.xxx.xxx.xxx.SystemLog)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
    SystemLog systemLog = ((MethodSignature)joinPoint.getSignature()).getMethod().getAnnotation(SystemLog.class);    
    ......
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值