注解丢失

最近在开发过程中遇到了注解被抹掉的情况。
背景:引入调度框架,接入方式很简单需要在job类上打上注解@Schedule(包含@Component)使其成为spring的bean,然后在类中方法打上@Assignment注解,这样通过这个bean获取method,在通过method方法过滤存在@Assignment注解的方法即可。

Class clazz = bean.getClass();
Method[] methods = clazz.getMethods();
if (methods != null && methods.length > 0) {
    for (final Method method : methods) {
        if (method.isAnnotationPresent(Assignment.class)) { 都为false
            ......
        }
    }
}

但是在使用时确总是筛选不出方法,都不带有@Assignment注解,明明已经打上了标签。

分析:因为项目中使用了spring aop cglib猜测是和这个有关系,为了清晰说明这个问题新建了个demo,目录结构如下:

注解丢失_第1张图片
目录结构

WillErase.java

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface WillErase {
}

EraseAspect.java

@Aspect
@Component
public class EraseAspect {

    @Pointcut(value = "@annotation(com.example.demo.anno.WillErase)")
    public void pointcut() {
    }

    @Around(value = "pointcut()")
    public void before(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("======begin=======");
        pjp.proceed();
        System.out.println("======end=======");
    }

}

AopTestService.java

@Service
public class AopTestService {
    @WillErase
    public void test() {

    }
}

AopTestController.java

@RestController
public class AopTestController {
    @Autowired
    private AopTestService aopTestService;

    @GetMapping(value = "testaop")
    public String testaop() {
        aopTestService.test();
        Class aClass = aopTestService.getClass();
        Method[] methods = aClass.getMethods();
        Optional first = Arrays.stream(methods)
                .filter(method -> method.isAnnotationPresent(WillErase.class))
                .findFirst();
        System.out.println(first.isPresent());
        return "";
    }
}

当执行testaop的时候获取到的method确实是没结果。我们逐步debug,看下method[]中的内容:

注解丢失_第2张图片
method数组

一个简单的aoptestservice里面发现存在43个方法,去掉我们原本的 test(),toString(),hashCode()...也不应该有这么多,仔细看都是cglib的enhancer给我们生成的,我们在看图中 test()方法的 annotations是null的,然后大概能猜到是因为enhancer引起的,那再去验证下这个动态代理的service生成过程
注解丢失_第3张图片
AopTestService

bingo!就是在生成这个代理类的时候test()方法上的注解被抹掉了,!-_-就不说过程了。需要参考 spring aop初始流程。

结论:当存在切面的时候使用enhancer生成代理类那么注解会被抹掉,即便注解是@Inherited注解。

你可能感兴趣的:(注解丢失)