Kai*_*zel 5 java spring spring-boot
我需要先初始化一个组件。使用@DependsOn,它看起来像这样:
@Component("beana")
public class BeanA{
@PostConstruct
void init(){
// do smth
}
}
@Component("beanb")
@DependsOn("beana")
public class BeanB{
@PostConstruct
void init(){
// do smth
}
}
Run Code Online (Sandbox Code Playgroud)
我现在必须告诉BeanB,它取决于BeanA的初始化。我的问题是我不希望BeanB知道BeanA的存在(例如,当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
}
}
Run Code Online (Sandbox Code Playgroud)
是否有任何Spring注释或像这样处理它的可能性?
我相信对此没有开箱即用的 spring 注释,但您可以轻松制作自己的注释。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RequiredBy {
String[] value();
}
Run Code Online (Sandbox Code Playgroud)
然后可以遍历所有 bean 定义并将dependsOn 设置为该requiredbean。
@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 { }
}
Run Code Online (Sandbox Code Playgroud)
然后像在你的例子中一样使用它:
@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());
}
}
Run Code Online (Sandbox Code Playgroud)
=>
BeanB
BeanC
BeanA
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
371 次 |
| 最近记录: |