2014-11-06 56 views
5

後初始化相關懶豆我有延遲初始化代碼豆:春:如何主bean創建

@Component @Lazy 
class Resource {...} 

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

初始化應用程序上下文後,有沒有這個bean的實例。當bean資源由應用程序上下文創建時(例如,applicationContext.getBean(Resource.class)),@CustomProcessor的實例都不標記bean。

當創建Resource bean時,需要使用@CustomProcessor創建bean。怎麼做?

更新時間: 醜陋的解決方案的一個發現 - 用空的自動裝配Autowired二傳手:

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

另一個醜陋的解決方案豆的BeanPostProcessor

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

也許有一個更優雅的方式(這樣神奇!)?

+0

@Lazy的java文檔形式如果存在並設置爲true,則@Bean或@Component將不會被初始化,直到被另一個bean引用或從封閉BeanFactory中顯式檢索到。我認爲你應該從處理器中刪除@Lazy或者在Resource bean中放置一個引用。 – Xstian 2014-11-06 13:54:58

+0

不,它不起作用,因爲ResourceProcessor不是Resource的依賴項。當所有組件都不是懶惰的,當然它工作正常,但我需要通過延遲初始化來實現 – mitallast 2014-11-06 14:41:56

+0

您可以在Resource中添加'@ PostConstruct'來初始化所有'Processor'。 – Xstian 2014-11-06 14:55:05

回答

3

您必須創建一個像CustomProcessor

public interface CustomProcessor{ 

} 

後一個標記接口,每個ResourceProcessor必須高於接口實現

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

資源必須實現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; 
    } 

} 

Resource豆會回覆ferenced啓動初始化所​​有實現了CustomProcessor接口的bean的postconstruct。

+0

不幸的是,這是一個很難的Spring框架供應商鎖定。 另外,最好使用'@ Autowired'作爲'ApplicationContext'而不使用'ApplicationContextAware' – mitallast 2014-11-07 12:20:22