gpt4 book ai didi

java - 在 Spring 上下文中查找方法级别的自定义注释

转载 作者:IT老高 更新时间:2023-10-28 13:58:59 27 4
gpt4 key购买 nike

我只想找出“Spring bean 中所有被注释为@Versioned 的类/方法”。

我将自定义注释创建为,

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

当我使用 Java 反射查找方法时,此注释完美运行:

for(Method m: obj.getClass().getMethods()){
if(m.isAnnotationPresent(Versioned.class)){
.... // Do something
}

但是当我访问 Spring bean 并尝试类似的检查时它不起作用:

public class VersionScanner implements ApplicationContextAware{
public void setApplicationContext(ApplicationContext applicationContext){
for(String beanName: applicationContext.getBeanDefinitionNames()){
for(Method m: applicationContext.getBean(beanName).getClass().getDeclaredMethods()){
if(m.isAnnotationPresent(Versioned.class){
// This is not WORKING as expected for any beans with method annotated
}
}
}
}
}

其实这段代码确实找到了@RequestMapping等其他注解。我不确定我的自定义注释做错了什么。

最佳答案

通过您的代码,我发现您正在使用带有 CGLIB 代理的 Spring AOP。由于您的类(具有使用 @Versioned 注释的方法)正在被代理。

我已经用你的代码库测试了这个解决方案。

使用以下代码,它应该可以解决您的问题。在代码片段下方寻找更多选项:

@Configuration
public class VersionScanner implements ApplicationContextAware {

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

for (String beanName : applicationContext.getBeanDefinitionNames()) {
Object obj = applicationContext.getBean(beanName);
/*
* As you are using AOP check for AOP proxying. If you are proxying with Spring CGLIB (not via Spring AOP)
* Use org.springframework.cglib.proxy.Proxy#isProxyClass to detect proxy If you are proxying using JDK
* Proxy use java.lang.reflect.Proxy#isProxyClass
*/
Class<?> objClz = obj.getClass();
if (org.springframework.aop.support.AopUtils.isAopProxy(obj)) {

objClz = org.springframework.aop.support.AopUtils.getTargetClass(obj);
}

for (Method m : objClz.getDeclaredMethods()) {
if (m.isAnnotationPresent(Versioned.class)) {
//Should give you expected results
}
}
}
}
}

检测代理类:

  • 对于使用任何代理机制的 Spring AOP 代理,请使用 org.springframework.aop.support.AopUtils#isAoPProxy
  • 如果您使用 Spring CGLIB 进行代理(不是通过 Spring AOP),请使用 org.springframework.cglib.proxy.Proxy#isProxyClass
  • 如果您使用 JDK Proxy 进行代理,请使用 java.lang.reflect.Proxy#isProxyClass

我刚刚写了一个 if 条件,在你的情况下就足够了;但如果使用多个代理工具,则必须根据上述信息编写多个 if-else 条件。

关于java - 在 Spring 上下文中查找方法级别的自定义注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27929965/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com