2014-11-06 55 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