注解丢失

最近在开发过程中遇到了注解被抹掉的情况。
背景:引入调度框架,接入方式很简单需要在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,目录结构如下:

目录结构

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<? extends AopTestService> aClass = aopTestService.getClass();
        Method[] methods = aClass.getMethods();
        Optional<Method> first = Arrays.stream(methods)
                .filter(method -> method.isAnnotationPresent(WillErase.class))
                .findFirst();
        System.out.println(first.isPresent());
        return "";
    }
}

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

method数组

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

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

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容