Spring Data Repository接口自定义参数注解反射检测失败问题
问题原因
Spring Data创建Repository实例时,会通过动态代理生成实现类,你现在反射的是代理类的方法,但@Encrypted注解定义在Repository接口的方法参数上,代理类的方法参数不会继承这些注解,所以直接拿代理类的方法参数注解自然找不到。而普通类没有代理层,直接反射类本身就能拿到注解,所以测试正常。
解决方案
要获取接口上的方法参数注解,需要先拿到Repository的接口类型,再遍历接口的方法来获取注解,而不是反射代理类的方法。修改后的检测代码如下:
@Configuration class EncryptionConfiguration { @Autowired SubscriptionRepository subscriptionRepository; @PostConstruct void method() { // 获取Repository的接口类型 Class<?> repositoryInterface = SubscriptionRepository.class; // 遍历接口的所有方法 Method[] methods = repositoryInterface.getMethods(); for (Method method : methods) { Annotation[][] annotationTab = method.getParameterAnnotations(); for (Annotation[] annotationRow : annotationTab) { for (Annotation annotation : annotationRow) { if (annotation instanceof Encrypted) { Encrypted encrypted = (Encrypted) annotation; // 这里可以处理你的注解逻辑 } } } } } }
如果要通用处理(不硬编码接口类),可以通过代理类获取实现的接口:
@PostConstruct void method() { Class<?>[] interfaces = subscriptionRepository.getClass().getInterfaces(); for (Class<?> intf : interfaces) { Method[] methods = intf.getMethods(); for (Method method : methods) { Annotation[][] annotationTab = method.getParameterAnnotations(); for (Annotation[] annotationRow : annotationTab) { for (Annotation annotation : annotationRow) { if (annotation instanceof Encrypted) { Encrypted encrypted = (Encrypted) annotation; // 处理逻辑 } } } } } }
补充说明
动态代理生成的类只是实现了Repository接口,它的方法是代理逻辑,不会保留接口方法参数上的注解元数据。所以必须从原始接口类中获取方法定义,才能拿到对应的参数注解。
内容的提问来源于stack exchange,提问作者Damian Tański
相关产品推荐
相关产品推荐

