All I wanted to find out was \"all the class/methods in Spring beans which are annotated as @Versioned\".
I created my custom annotation as,
@Target({Ele
applicationContext.getBean(beanName).getClass()
gives you the proxied class that Spring creates around your target class.
What you want is to get hold of the target class, if any, from your Spring bean.
Spring provides a nice utility class for resolving this called AopUtils.class.
Below is how you would use it:
for(String beanName: applicationContext.getBeanDefinitionNames()){
Method[] methods = AopUtils.getTargetClass(applicationContext.getBean(beanName)).getDeclaredMethods();
for(Method m: methods){
if(m.isAnnotationPresent(Versioned.class){
}
}
}
Note that you will have to import the spring-aop
Maven dependency to get hold of the AopUtils class:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
Going through your code, I figured out that you are using Spring AOP with CGLIB Proxying. Due to which your classes (which have methods annotated with @Versioned
) are being proxied.
I have tested this solution with your code base.
Use the following code, and it should resolve your issue. Look for more options below the code snippet:
@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
}
}
}
}
}
To detect a proxy class:
org.springframework.aop.support.AopUtils#isAoPProxy
org.springframework.cglib.proxy.Proxy#isProxyClass
java.lang.reflect.Proxy#isProxyClass
I have just written one if
condition which is sufficient in your case; but in case multiple proxying utilities are used, multiple if-else
conditions will have to be written based on the information above.
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?
}
}
}
}
}