2014-11-06 11 views
5

Ho codice con i fagioli inizializzati pigri:primavera: come inizializzare correlati fagioli pigri dopo la creazione di fagioli principale

@Component @Lazy 
class Resource {...} 

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

Dopo contesto di applicazione di inizializzazione, non c'è nessun caso di questo fagioli. Quando la risorsa bean viene creata dal contesto dell'applicazione (ad esempio, applicationContext.getBean (Resource.class)), nessuna istanza di @CustomProcessor ha contrassegnato i bean.

È necessario creare bean con @CustomProcessor quando viene creato il bean di risorse. Come farlo?

Aggiornato: Uno dei brutti soluzione trovata - utilizzare vuoto autowired setter:

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

Un'altra brutta soluzione con il fagiolo BeanPostProcessor

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

Forse c'è un modo più elegante (così magico!)?

+0

Form java docs di @Lazy 'Se presente e impostato su true, @Bean o @Component non verranno inizializzati fino a quando non vengono referenziati da un altro bean o recuperati esplicitamente dall'accluso BeanFactory'. Penso che dovresti rimuovere @Lazy dal processore o inserire un riferimento all'interno del bean Resource. – Xstian

+0

No, non funziona perché ResourceProcessor non è una dipendenza per Risorsa. Quando tutti i componenti non sono pigri, naturalmente, funziona correttamente, ma ho bisogno di farlo con l'inizializzazione pigra – mitallast

+0

È possibile aggiungere un '@ PostConstruct' all'interno di Risorsa per inizializzare tutto' Processore'. – Xstian

risposta

3

È necessario creare un'interfaccia marcatore come CustomProcessor

public interface CustomProcessor{ 

} 

dopo ogni ResourceProcessor deve essere strumenti di cui sopra interfaccia

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

risorsa deve implementa 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; 
    } 

} 

Quando Resource fagiolo sarà ri ferenced avvia la postconstruct che inizializza tutto il bean che implementa l'interfaccia CustomProcessor.

+0

Sfortunatamente, è un duro blocco del fornitore di Spring Framework. Inoltre, è meglio usare '@ Autowired' per' ApplicationContext' senza 'ApplicationContextAware' – mitallast