Is there a "return" to Spring @DependsOn annotation?

I need one component to initialize before another. With @DependsOn it will 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
    }
}

Now I have to tell BeanB that it depends on the initialization of BeanA. My problem is that I do not want BeanB to know about the existence of BeanAs (for example, when BeanB just publishes events in an EventBus, and BeanA initializes and processes these events). I would like to use annotation in BeanA, stating that it must be initialized before BeanB. So, it will be 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
    }
}

Is there any annotation or the ability to handle it like this?

+4
source share
2 answers

, spring, .

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

bean dependOn 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
+1

@Order, pvpkiran.

:

@Component("beana")
@Order(1)
public class BeanA{

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

@Component("beanb")
@Order(2)
public class BeanB{

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

Source: https://habr.com/ru/post/1678859/


All Articles