是否有“恢复"?到 Spring @DependsOn 注释? [英] Is there a "revert" to Spring @DependsOn annotation?

查看:25
本文介绍了是否有“恢复"?到 Spring @DependsOn 注释?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在另一个组件之前初始化一个组件.使用@DependsOn,它看起来像这样:

I need one Component to be initialized before another. With @DependsOn it would look something like this:

@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 之前初始化.所以它会是这样的:

I now have to tell BeanB that it depends on the initialization of BeanA. My problem is that I do not want BeanB to know about BeanAs existance (e.g, when BeanB is just publishing Events in an EventBus while initializing and BeanA handles these events). I would like to use an annotation at BeanA stating it should bei initialized before BeanB. So it would something like this:

@Component("beana")
@RequiredBy("beanb") 
public class BeanA{

    @PostConstruct
    void init(){
       // do smth
    }
}

@Component("beanb")
public class BeanB{

    @PostConstruct
    void init(){
       // do smth
    }
}

是否有任何 Spring 注释或可能像这样处理它?<​​/p>

Is there any Spring annotation or possibility to handle it like this?

推荐答案

我相信对此没有现成的 spring 注释,但您可以轻松制作自己的注释.

I believe there is no out of the box spring annotation for this, but you can easily make your own one.

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

然后可以遍历所有 bean 定义并将dependsOn 设置为那个required bean.

Then it is possible to iterate through all bean definitions and set dependsOn to that 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 { }
}

然后像你的例子一样使用它:

And then use it like in you example:

@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

这篇关于是否有“恢复"?到 Spring @DependsOn 注释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆