Reputation: 327
UPDATE: I used a different approach for my problem.
Side-Question: I would like to know how spring does it with the exclude in SpringBootApplication
The SpringBootApplication:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class))
public @interface SpringBootApplication {
So when the context is loaded, and the EnableAutoConfiguration is executed, the excludes are available.
Thats the same what i want.
At Bean-Creation i want to know if an Annotation has some field (for example boolean)
Old Question:
I have an Annotation:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(TaskSpringContext.class)
public @interface TaskTest
{
Class<? extends DatabaseService> db() default DatabaseService.class;
}
This Annotation is used at:
@TaskTest(db = DatabaseServiceExtended.class)
@SpringBootApplication()
public class TaskServer
{
public static void main(String[] args)
{
final ApplicationContext ctx = SpringApplication.run(TaskServer.class, args);
}
}
Now, at TaskSpringContext.class i want to create a bean based on the db-Field of the TaskTest-Annotation:
@Bean(name = "databaseService")
public DatabaseService databaseService()
{
return ??
Here i want to return the DatabaseServiceExtended
}
Anyone knows how to do it?
Upvotes: 0
Views: 2146
Reputation: 10652
I assume that there's a better way for it, but this will scan your classpath, starting from "com.example" for all classes annotated with com.example.TaskTest
and add a bean definition for it, so that bean will be created later.
This will allow you to check all classes for your annotation, but of course you will have to solve the problem that two (or more) @TaskTest
could be on your classpath.
@Component
public class TestBeanProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
; // does nothing
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
Set<BeanDefinition> definitions = scanForBeanDefinitionsIn("com.example"); // the base package
// test if one or more, perhaps error, whatever
BeanDefinition def = ...; // one of them
Class<?> clz = Class.forName(def.getBeanClassName());
TaskTest annotation = clz.getAnnotation(TaskTest.class);
// create new RootBeanDefinition with TaskText Data (pretty analogous to XML)
RootBeanDefinition dataSourceDefinition = ...;
registry.registerBeanDefinition("dataSource", dataSourceDefinition);
}
protected Set<BeanDefinition> scanForBeanDefinitionsIn(String basePackage) {
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
return metadataReader.getAnnotationMetadata().getAnnotationTypes().contains("com.example.TaskTest");
}
});
return scanner.findCandidateComponents(basePackage);
}
}
Upvotes: 1