简体   繁体   English

如何确保在初始化容器之前首先初始化一组实现接口的 Spring 引导 bean?

[英]How to ensure a set of Spring boot beans implementing an interface being first initalized before their container being initalized?

I have a set of beans both implementing an interface我有一组 bean 都实现了一个接口

@Componet
class BeanA implements interfaceA{
   public void process(){
   }
}

@Componet
class BeanB implements interfaceA{
   public void process(){
   }
}

I want to get all beans of interfaceA and apply their process methods sequentially, so I have a container to collect these beans.我想获取 interfaceA 的所有 beans 并按顺序应用它们的 process 方法,因此我有一个容器来收集这些 beans。

@Componet
class Container{

List<interfaceA> container;

@Autowired
private ApplicationContext applicationContext;    

@PostConstruct
public void init()
{
    container=applicationCOntext.getBeansOfType(interfaceA.class).values().stream().collect(Collections.list());
    for(obj:container){
        obj.process();
    }
}

So how can I ensure Container be initialized after all beans of interfaceA, so I can get all beans of interfaceA in init() method of Container?那么如何确保在interfaceA的所有bean之后初始化Container,以便我可以在Container的init()方法中获取interfaceA的所有bean?

Or put it another way, can applicationContext.getBeansOfType always get all beans of interfaceA?或者换个说法,applicationContext.getBeansOfType 能不能一直获取interfaceA的所有bean? what if Container get initialzed first?如果 Container 先初始化呢?

By the way, Container does not have to be a componet.顺便说一下,Container 不必是一个组件。

You can inject a list with all the components implementing interfaceA :您可以注入一个包含所有实现interfaceA的组件的列表:

@Componet
class Container{

    @Autowired
    List<interfaceA> container;

    @PostConstruct
    public void init()
    {
        for(obj : container){
            obj.process();
        }
    }
}

In such a case you don't need to worry about components creation order, Spring is smart enough to make it right.在这种情况下,您无需担心组件创建顺序,Spring 足够聪明,可以使它正确。

Components scanning/initialization is a two-step process.组件扫描/初始化是一个两步过程。 First, Spring collects all beans definitions and builds a dependency graph (without creating any beans).首先,Spring 收集所有 bean 定义并构建一个依赖关系图(不创建任何 bean)。 After that, it knows in what order the beans should be initialized.之后,它知道应该以什么顺序初始化 bean。 When you inject interfaceA beans as a list, Spring knows, that the Container instance depends on them and will initialize them first.当您将interfaceA bean 作为列表注入时,Spring 知道, Container实例依赖于它们,并将首先初始化它们。 It wouldn't be the case if you obtained the components manually from the ApplicationContext (the dependency would be hidden) and you would need @DependsOn annotations on the interfaceA components.如果您从ApplicationContext手动获取组件(依赖项将被隐藏),则情况并非如此,并且您需要在interfaceA组件上添加 @DependsOn 注释。

  1. You can use @DependsOn(value = {"beanA", "beanB"}) on you Container class.您可以在Container类上使用@DependsOn(value = {"beanA", "beanB"})

  2. And Make your Container class implement InitializingBean interface and override the afterPropertiesSet() method.并使您的Container类实现InitializingBean接口并覆盖afterPropertiesSet()方法。

  3. And then move the logic that you've written in init method to afterPropertiesSet() method.然后将您在init方法中编写的逻辑移动到afterPropertiesSet()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM