簡體   English   中英

Spring @DependsOn注釋是否有“恢復”?

[英]Is there a “revert” to Spring @DependsOn annotation?

我需要在另一個組件之前初始化一個組件。 使用@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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM