2014-11-06 7 views
5

Ich habe Code mit faul initialisierte Bohnen zu initialisieren:Spring: wie ähnliche faule Bohnen nach der Erstellung Haupt Bohne

@Component @Lazy 
class Resource {...} 

@Component @Lazy @CustomProcessor 
class ResourceProcessorFoo{ 
    @Autowired 
    public ResourceProcessor(Resource resource) {...} 
} 
@Component @Lazy @CustomProcessor 
class ResourceProcessorBar{ 
    @Autowired 
    public ResourceProcessor(Resource resource) {...} 
} 

Nach initialize Anwendungskontext, gibt es keine Instanzen dieser Bohnen. Wenn die Bean-Ressource vom Anwendungskontext erstellt wird (z. B. applicationContext.getBean (Resource.class)), wurden keine Instanzen von @CustomProcessor als Beans markiert.

Es müssen Beans mit @CustomProcessor erstellt werden, wenn Resource Bean erstellt wird. Wie es geht?

Aktualisiert: Eine hässliche Lösung gefunden - verwenden leer autowired Setzer:

@Autowired 
public void setProcessors(List<ResourceProcessor> processor){} 

Eine andere hässliche Lösung mit Bohnen BeanPostProcessor

@Component 
class CustomProcessor implements BeanPostProcessor{ 
    public postProcessBeforeInitialization(Object bean, String beanName) { 
     if(bean instanceof Resource){ 
      applicationContext.getBeansWithAnnotation(CustomProcessor.class); 
     } 
    } 
} 

Vielleicht ein eleganter Weg, es gibt (so Magie!)?

+0

Formular java docs von @Lazy 'Wenn vorhanden und auf true gesetzt, wird @Bean oder @Component erst initialisiert, wenn es von einer anderen Bean referenziert oder explizit aus der einschließenden BeanFactory abgerufen wird. Ich denke, dass Sie @Lazy vom Prozessor entfernen oder einen Verweis in Resource Bean einfügen sollten. – Xstian

+0

Nein, es funktioniert nicht, da ResourceProcessor keine Abhängigkeit von Resource ist. Wenn alle Komponenten nicht faul sind, funktioniert es natürlich korrekt, aber ich muss es mit einer lazinen Initialisierung machen. – mitallast

+0

Sie könnten ein '@ PostConstruct' in Resource hinzufügen, um alle' Prozessoren' zu initialisieren. – Xstian

Antwort

3

Sie müssen eine Markierungsschnittstelle wie CustomProcessor

public interface CustomProcessor{ 

} 

erstellen später jede ResourceProcessor Geräte über Schnittstelle

@Component @Lazy 
class ResourceProcessorFoo implements CustomProcessor{ 
    @Autowired 
    public ResourceProcessor(Resource resource) {...} 
} 
@Component @Lazy 
class ResourceProcessorBar implements CustomProcessor{ 
    @Autowired 
    public ResourceProcessor(Resource resource) {...} 
} 

Ressource wird ApplicationContextAware

@Component 
@Lazy 
public class Resource implements ApplicationContextAware{ 

    private ApplicationContext applicationContext; 

    @PostConstruct 
    public void post(){ 
     applicationContext.getBeansOfType(CustomProcessor.class); 
    } 

    public void setApplicationContext(ApplicationContext applicationContext)throws BeansException { 
     this.applicationContext = applicationContext; 
    } 

} 

Wenn Resource Bohne sein muss implementiert, muss Re Ferenced startet das Postconstruct, das alle Bean initialisiert, die die Schnittstelle CustomProcessor implementiert.

+0

Leider ist es eine harte Spring Framework Vendor Lock. Es ist auch besser, '@ Autowired' für' ApplicationContext' ohne 'ApplicationContextAware' zu ​​verwenden – mitallast

Verwandte Themen