[英]Is there a “revert” to Spring @DependsOn annotation?
I need one Component to be initialized before another. 我需要在另一个组件之前初始化一个组件。 With @DependsOn it would look something like this:
使用@DependsOn,它看起来像这样:
@Component("beana")
public class BeanA{
@PostConstruct
void init(){
// do smth
}
}
@Component("beanb")
@DependsOn("beana")
public class BeanB{
@PostConstruct
void init(){
// do smth
}
}
I now have to tell BeanB that it depends on the initialization of BeanA. 我现在必须告诉BeanB它取决于BeanA的初始化。 My problem is that I do not want BeanB to know about BeanAs existance (eg, when BeanB is just publishing Events in an EventBus while initializing and BeanA handles these events).
我的问题是我不希望BeanB知道BeanAs存在(例如,当BeanB在初始化时只在EventBus中发布事件并且BeanA处理这些事件时)。 I would like to use an annotation at BeanA stating it should bei initialized before BeanB.
我想在BeanA上使用一个注释,说它应该在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
}
}
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();
}
Then it is possible to iterate through all bean definitions and set dependsOn to that required
bean. 然后可以遍历所有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 { }
}
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
You can use the @Order annotation as recommended by pvpkiran . 您可以按照pvpkiran的建议使用@Order注释。
Your code would look something like this: 您的代码看起来像这样:
@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.