@Repeatable与重复注解的使用

1. @Repeatable注解

@Repeatable是JDK1.8出现的元注解,在早前的版本中声明的注解Annotation是不能够重复作用在同一个类或方法上的,而有些时候我们的开发偏偏需要这样的使用诉求和场景。

2.@Repeatable使用

单一注解的使用方式如下:

/**
 * created by guanjian on 2020/11/30 19:58
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Aop {

    String value() default "";
}

引入@Repeatable注解后,改造如下:

/**
 * created by guanjian on 2020/11/30 19:58
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(Aops.class) //这里作用在业务注解上
public @interface Aop {

    String value() default "";
}

引入了@Aops返回@Aop数组以支持@Aop多次注解重复使用

/**
 * created by guanjian on 2020/11/30 19:58
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Aops {

    Aop[] value(); //这里返回的是业务注解@Aop的数组
}

3.Aspect切面

/**
 * created by guanjian on 2020/11/30 20:00
 */
@Aspect
@Component("aopAspect")
public class AopAspect {

    @Resource
    private TransactionTemplate transactionTemplate;
	
    @Around("@annotation(com.github.java.learning.spring.aop.annotation.Aop) " +
            "|| @annotation(com.github.java.learning.spring.aop.annotation.Aops)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Aop[] aops = getMethod(pjp).getAnnotationsByType(Aop.class);
        Stream.of(aops).forEach(x->{
            System.out.format("value=== %s\n", x.value());
        });

        return pjp.proceed();
    }

    protected Method getMethod(ProceedingJoinPoint pjp) {
        Method method = null;
        try {
            MethodSignature ms = (MethodSignature) pjp.getSignature();
            method = pjp.getTarget()
                    .getClass()
                    .getMethod(ms.getName(), ms.getParameterTypes());
        } catch (NoSuchMethodException e) {
            //ignore
        }
        return method;
    }
}

4.Service方法

/**
 * created by guanjian on 2020/11/30 20:13
 */
@Component("aopService")
public class AopService {

    @Aop("a")
    @Aop("c")
    @Aop("b")
    public Object test(User req) {
        return new Object();
    }
}

5.使用总结

关于多个注解的使用总结如下:

拦截注解使用注解个数getAnnotationgetAnnotationsByType
@Aop单个
@Aop多个××
@Aops单个××
@Aops多个×
@Aop + @Aops单个
@Aop + @Aops多个×
  • 使用的时候,为了支持单个和多个的可扩展性,@Around配置同时拦截@Aop和@Aops,通过getAnnotationsByType获取注解数组来获取注解对象进行逻辑操作

  • 通过getAnnotationsByType获取到的 Annotation[] 注解数组也是按照方法的存放顺序由上到下存储的,是有顺序性的,比如按照@Aop(“a”)、@Aop(“c”)、@Aop(“b”)进行配置,则拿到a、c、b的Annotation对象

  • 业务方法被多个相同注解使用,只在一个Aspect切面中使用一次,也就是说Service方法执行一次,Aspect只拦截一次,不会因为多个注解而拦截多次,这是和不同注解作用于一个方法不同
    在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大摩羯先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值