Spring @DependsOn注释是否有"revert"?



我需要先初始化一个组件,然后再初始化另一个组件。使用@DependsOn,它看起来像这样:

@Component("beana")
public class BeanA{
    @PostConstruct
    void init(){
       // do smth
    }
}
@Component("beanb")
@DependsOn("beana")
public class BeanB{
    @PostConstruct
    void init(){
       // do smth
    }
}

我现在必须告诉 BeanB,这取决于 BeanA 的初始化。我的问题是我不想让 BeanB 知道 BeanAs 的存在(例如,当 BeanB 在初始化时只是在 EventBus 中发布事件并且 BeanA 处理这些事件时(。我想在 BeanA 上使用一个注释,说明它应该在 BeanB 之前初始化。所以它会像这样:

@Component("beana")
@RequiredBy("beanb") 
public class BeanA{
    @PostConstruct
    void init(){
       // do smth
    }
}
@Component("beanb")
public class BeanB{
    @PostConstruct
    void init(){
       // do smth
    }
}

有没有 Spring 注释或像这样处理它的可能性?

我相信

没有开箱即用的弹簧注释,但你可以很容易地制作自己的注释。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RequiredBy {
    String[] value();
}

然后,可以遍历所有 bean 定义并将 dependsOn 设置为该required bean。

@Component
public static class RequiredByBeanDefinitionPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        for (String beanName : registry.getBeanDefinitionNames()) {
            final BeanDefinition beanDefinition = registry.getBeanDefinition(beanName);
            if (beanDefinition.getBeanClassName() == null) {
                continue;
            }
            try {
                final Class<?> beanClass = Class.forName(beanDefinition.getBeanClassName());
                if (beanClass.isAnnotationPresent(RequiredBy.class)) {
                    final String[] dependantBeanNames = beanClass.getAnnotation(RequiredBy.class).value();
                    for (String dependantBeanName : dependantBeanNames) {
                        BeanDefinition dependantBeanDefinition = registry.getBeanDefinition(dependantBeanName);
                        dependantBeanDefinition.setDependsOn(beanName);
                    }
                }
            }
            catch (ClassNotFoundException e) { throw new RuntimeException(e); }
        }
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { }
}

然后像在示例中一样使用它:

@Component("beanA")
public static class BeanA {
    @PostConstruct
    private void init() {
        System.out.println(this.getClass().getSimpleName());
    }
}
@Component("beanB")
@RequiredBy({ "beanC", "beanA" })
public static class BeanB {
    @PostConstruct
    private void init() {
        System.out.println(this.getClass().getSimpleName());
    }
}
@Component("beanC")
@RequiredBy("beanA")
public static class BeanC {
    @PostConstruct
    private void init() {
        System.out.println(this.getClass().getSimpleName());
    }
}

=>

BeanB
BeanC
BeanA

您可以使用 pvpkiran 推荐的@Order注释。

您的代码如下所示:

@Component("beana")
@Order(1)
public class BeanA{
@PostConstruct
    void init(){
       // do smth
    }
}
@Component("beanb")
@Order(2)
public class BeanB{
    @PostConstruct
    void init(){
       // do smth
    }
}

最新更新