2016-08-23 6 views
0

UPDATE: Ich habe einen anderen Ansatz für mein Problem verwendet.Frühling - Erstelle Bean basierend auf Annotation-Feld

Side-Frage: Ich würde gerne wissen, wie Frühling macht es mit dem Ausschluß in SpringBootApplication

Die SpringBootApplication:

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

Also, wenn der Kontext geladen wird, und die EnableAutoConfiguration ausgeführt wird , die Ausschlüsse sind verfügbar.

Das ist das gleiche was ich will.

Bei Bean-Creation mag ich wissen, ob eine Annotation einige Felder (zB boolean) hat

Alte Frage:

ich eine Anmerkung habe:

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

Diese Annotation wird verwendet bei:

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

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

} 

Nun, bei TaskSpringContext.class mag ich eine Bohne erstellen auf der Grundlage des db-Gebiet der TaskTest-Annotation:

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

Jeder weiß, wie es zu tun?

+0

Es gibt keine Garantie, dass nur eine @SpringBootApplication auf Ihrem Klassenpfad vorhanden ist ... Was also möchten Sie? Der, wo Ihre Hauptmethode ist? Während es Möglichkeiten gibt, die Hauptklasse zu bekommen, ist keiner von ihnen ziemlich gut, wenn du mich fragst. Vielleicht möchten Sie vielleicht nach Alternativen suchen, weil ich ziemlich überzeugt bin, dass es einen besseren Weg gibt, das zu tun, was Sie tun wollen, basierend auf dem Anwendungsfall. –

+0

Die SpringBootApplication Annotation hat ein Feld "exclude". Dort können Sie Klassen angeben. Diese Klassen müssen etwas gelesen werden. Es ist das gleiche was ich will. Ich möchte eine Bean mit einer Annotation erstellen und das Feld der Annotation soll helfen, die Bean zu erstellen. – Hesk

+0

Es ist keine gute Übung, Ihre Fragen so zu bearbeiten, aber der Übersichtlichkeit halber ... Spring Annotation erstellt meistens nur Klassen/Beans. In diesem Fall sollte meine Antwort unten helfen, da '@ ComponentScan' (und seine ältere XML-Variante' ') grundsätzlich eine Variante des' ClassPathScanningCandidateComponentProvider' verwendet, um Beans zu finden. Der Ausschluss fügt einfach einen Ausschlussfilter zu diesem Objekt hinzu, sodass einige Beans nicht berücksichtigt werden. Sie können das Ganze unter 'org.springframework.context.annotation.ComponentScanBeanDefinitionParser' auschecken –

Antwort

0

Ich gehe davon aus, dass es einen besseren Weg dafür gibt, aber dies wird Ihren Klassenpfad scannen, beginnend mit "com.example" für alle mit com.example.TaskTest annotierten Klassen und fügen Sie eine Bean-Definition hinzu, damit Bean später erstellt wird.

Damit können Sie alle Klassen für Ihre Annotation überprüfen, aber natürlich müssen Sie das Problem lösen, dass zwei (oder mehr) @TaskTest auf Ihrem Klassenpfad sein könnten.

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