I'm making a library to be used with Spring Boot. This lib define some annotations that can be used in methods.
How can I find (at runtime) the package of the application where the library is being used?
I need this in order to scan for the annotated methods.
You can implement BeanFactoryPostProcessor:
1. Using ConfigurableListableBeanFactory you can iterate over BeanDefinition
2. Determine if bean's class
has your annotation
3. Get the package from the bean's class
name
Example:
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Set<String> packages = findAnnotationUsagePackages(MyAnnotation.class, beanFactory);
...
}
private Set<String> findAnnotationUsagePackages(Class<? extends Annotation> annotationClass,
ConfigurableListableBeanFactory beanFactory) {
Set<String> annotationUsagePackages = new HashSet<>();
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);
if (beanDefinition instanceof ScannedGenericBeanDefinition) {
ScannedGenericBeanDefinition genericBeanDefinition = (ScannedGenericBeanDefinition) beanDefinition;
if (AnnotationUtils.isCandidateClass(genericBeanDefinition.getBeanClass(), annotationClass)) {
String beanClassName = genericBeanDefinition.getBeanClassName();
if (beanClassName != null) {
annotationUsagePackages.add(ClassUtils.getPackageName(beanClassName));
}
}
}
}
return annotationUsagePackages;
}
}
About the AnnotationUtils.isCandidateClass():
Determine whether the given class is a candidate for carrying the specified annotation (at type, method or field level)
Also pay attention to the AbstractBeanDefinition.getBeanClass():
Throws: IllegalStateException - if the bean definition does not define a bean class, or a specified bean class name has not been resolved into an actual Class yet
P.S. also you can collect classes or meta-information inside AnnotationUtils.isCandidateClass
condition block