Spring - 基于Annotation字段创建bean

时间:2016-08-23 17:39:39

标签: spring

更新:我对我的问题使用了不同的方法。

Side-Question:我想知道spring如何使用SpringBootApplication中的exclude

SpringBootApplication:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class))
public @interface SpringBootApplication {

因此,当加载上下文并执行EnableAutoConfiguration时,可以使用排除。

这就像我想要的那样。

在Bean-Creation中,我想知道Annotation是否有某个字段(例如boolean)

旧问题:

我有一个注释:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(TaskSpringContext.class)
public @interface TaskTest
{
    Class<? extends DatabaseService> db() default DatabaseService.class;
}

此注释用于:

@TaskTest(db = DatabaseServiceExtended.class)
@SpringBootApplication()
public class TaskServer
{

    public static void main(String[] args)
    {
        final ApplicationContext ctx = SpringApplication.run(TaskServer.class, args);
    }

}

现在,在TaskSpringContext.class中,我想基于TaskTest-Annotation的db-Field创建一个bean:

@Bean(name = "databaseService")
public DatabaseService databaseService()
{
    return ??
    Here i want to return the DatabaseServiceExtended
}

任何人都知道怎么做?

1 个答案:

答案 0 :(得分:0)

我认为有一种更好的方法,但是这将扫描你的类路径,从“com.example”开始为所有注释了com.example.TaskTest的类,并为它添加一个bean定义,这样bean将是后来创建。

这将允许您检查注释的所有类,但当然您必须解决两个(或更多)@TaskTest可能在您的类路径上的问题。

@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);
    }
}