[英]Find method level custom annotation in a Spring context
我想知道的是“ 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。 我不確定自定義注釋我做錯了什么。
通過你的代碼,我發現你正在使用Spring AOP和CGLIB Proxying。 由於您的類(具有使用@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
}
}
}
}
}
要檢測代理類:
org.springframework.aop.support.AopUtils#isAoPProxy
org.springframework.cglib.proxy.Proxy#isProxyClass
java.lang.reflect.Proxy#isProxyClass
我剛才寫一個if
條件是你的情況充足; 但是如果使用多個代理實用程序, if-else
必須根據上述信息編寫多個if-else
條件。
applicationContext.getBean(beanName).getClass()
為您提供Spring在目標類周圍創建的代理類。
你想要的是從你的Spring bean中獲取目標類(如果有的話)。
Spring提供了一個很好的實用程序類來解析這個名為AopUtils.class的實用程序。
以下是如何使用它:
for(String beanName: applicationContext.getBeanDefinitionNames()){
Method[] methods = AopUtils.getTargetClass(applicationContext.getBean(beanName)).getDeclaredMethods();
for(Method m: methods){
if(m.isAnnotationPresent(Versioned.class){
}
}
}
請注意,您必須導入spring-aop
Maven依賴項才能獲取AopUtils類:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
for (String beanName : applicationContext.getBeanDefinitionNames()) {
Object obj = applicationContext.getBean(beanName);
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(Transactional.class)) {
Transactional transactional = m.getAnnotation(Transactional.class);
Class<? extends Throwable>[] value = transactional.rollbackFor();
if (value == null){
// help !!!
// If value is null, I want to set a value for him like Exception.class How can I modify it?
}
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.