2014-11-06 14 views
5

sonra ilgili tembel fasulye başlatmak için nasıl tembel başlatıldı fasulye kod var:Bahar: Ana fasulye oluşturma

@Component @Lazy 
class Resource {...} 

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

initialize uygulama bağlamında sonra bu fasulye hiçbir örneği yoktur. Fasulye Kaynağı, uygulama bağlamı tarafından oluşturulduğunda (örneğin, applicationContext.getBean (Resource.class)), @CustomProcessor'un hiçbir örneği fasulye işaretlemez.

Kaynak çekirdeği oluşturulduğunda @CustomProcessor ile fasülyenin oluşturulması gerekir. Nasıl yapılır?

Güncelleme: çirkin çözümün biri Bulunan - Boş autowired ayarlayıcı kullanın: (! Yüzden sihirli) fasulye BeanPostProcessor

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

Belki daha zarif bir yolu vardır ile

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

Başka çirkin çözüm?

+0

Form java docs @Lazy 'Varsa ve true olarak ayarlanırsa, @Bean veya @Component başka bir fasulyenin referans verene kadar veya eklenecek BeanFactory'den açıkça alınana kadar başlatılamaz. İşlemciden @Lazy'yi kaldırmanız veya Kaynak çekirdeğinin içine bir referans koymanız gerektiğini düşünüyorum. – Xstian

+0

Hayır, ResourceProcessor, Resource için bir bağımlılık olmadığı için işe yaramıyor. Tüm bileşenler tembel olmadığında, elbette doğru çalışır, ancak tembel başlatma – mitallast

+0

ile yapmam gerekiyor Tüm 'İşlemciyi 'başlatmak için Kaynak içinde' @ PostConstruct' ekleyebilirsiniz. – Xstian

cevap

3

Sen Resource fasulye olacak zaman

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

Kaynak 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; 
    } 

} 

uygulayan gerekir her ResourceProcessor arayüzüne yukarıdaki uygular olmalıdır CustomProcessor

public interface CustomProcessor{ 

} 

sonra böyle bir işaretleyici arabirimini oluşturmalısınız yeniden ferüle, CustomProcessor arayüzünü uygulayan tüm fasulyeyi başlatan postkontayı başlatır.

+0

Ne yazık ki, zor bir Bahar Çerçeve satıcı kilidi. Ayrıca, ApplicationContextAware işlevi olmadan "ApplicationContext" için 'Autowired 'kullanmak daha iyidir. – mitallast