2016-08-23 3 views
0

ОБНОВЛЕНИЕ: Я использовал другой подход для своей проблемы.Spring - Create bean on the Annotation field

Побочного Вопрос: Я хотел бы знать, как весна делает это с исключающим в SpringBootApplication

В 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 я хочу знать, если аннотации имеют некоторое поле (например, булевы)

Старый Вопрос:

У меня есть аннотация:

@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-Аннотация:

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

Каждый знает, как это сделать?

+0

Нет гарантии, что на вашем пути к классам есть только одна @SpringBootApplication ... Итак, какой из них вы хотите? Тот, где ваш основной метод? Хотя есть способы получить основной класс, ни один из них не очень хорош, если вы спросите меня. Поэтому, возможно, вам захочется поискать альтернативы, потому что я вполне уверен, что есть лучший способ сделать то, что вы хотите сделать, на основе прецедента. –

+0

В аннотации SpringBootApplication есть поле "exclude". Там вы можете указать классы. Эти классы должны быть прочитаны. Это то же самое, чего я хочу. Я хочу создать компонент с аннотацией, и поле аннотации должно помочь создать Bean. – Hesk

+0

Это не очень хорошая практика, чтобы отредактировать ваши вопросы так много, но для ясности ... Весенняя аннотация главным образом просто создает классы/бобы. В этом случае мой ответ ниже должен помочь, поскольку '@ ComponentScan' (и более старый вариант xml' ') в основном использует вариант' ClassPathScanningCandidateComponentProvider' для поиска beans. Исключить просто добавляет фильтр исключения к этому объекту, так что некоторые компоненты не будут рассматриваться. Вы можете проверить все это на 'org.springframework.context.annotation.ComponentScanBeanDefinitionParser' –

ответ

0

Я предполагаю, что для этого есть лучший способ, но это сканирует ваш путь к классам, начиная с «com.example» для всех классов, аннотированных с com.example.TaskTest, и добавляет для него определение компонента, так что 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); 
    } 
}