如何告诉Spring在应用运行时再次检查ConditionalOnBean ?



在一些bean上,我使用ConditionalOnBean(在示例中使用ab)。在应用程序启动时,它所依赖的bean并不存在。因此,注释(ConditionalOnBean)下的bean(示例中的yoni)没有被初始化,也没有被Spring处理。在运行应用程序的过程中,bean被动态地添加到上下文中(参见示例中的addYoni)。为了初始化现在通过条件(示例中的ab)的bean,我需要告诉Spring再次检查所有条件。需要注意的是,在现实世界中,我不知道哪些类处于相关条件下(事实上,其中一些还没有被写出来)。

如果可能的话,怎么做呢?

@ConditionalOnBean(name = "yoni")
@Service
public class a {
.
.
.
}
@ConditionalOnBean(name = "yoni")
@Service
public class b {
.
.
.
}
@Service
public class d {
@Autowired
private ApplicationContext applicationContext;
public void addYoni(){
ConfigurableApplicationContext configContext = (ConfigurableApplicationContext) applicationContext;
DefaultListableBeanFactory beanRegistry = (DefaultListableBeanFactory) configContext.getBeanFactory();
beanRegistry.registerSingleton("yoni", yoni());

// What Should be written here to cause Spring to check and to inject the under-conditions classes into the application context?
}

public Rab yoni() {
Rab rab = new rab();
.
.
.        
return rab;  
} 
}

最后,我找到了这样做的方法。它需要查找带有注释ConditionalOnBean的类,并从中创建一个bean。下面是代码(问题中的类d):

@Service
public class d {
@Autowired
private ApplicationContext applicationContext;

public void addC(){
ConfigurableApplicationContext configContext = (ConfigurableApplicationContext) applicationContext;
DefaultListableBeanFactory beanRegistry = (DefaultListableBeanFactory) configContext.getBeanFactory();
beanRegistry.registerSingleton("yoni", yoni());
ClassPathScanningCandidateComponentProvider componentProvider =
new ClassPathScanningCandidateComponentProvider(false);
componentProvider.addIncludeFilter(new AnnotationTypeFilter(ConditionalOnBean.class));
Set<BeanDefinition> candidateComponents = componentProvider.findCandidateComponents("base.project.package");
candidateComponents.forEach(beanDefinition -> {
String className = beanDefinition.getBeanClassName().substring(beanDefinition.getBeanClassName().lastIndexOf('.') + 1);
String beanName = Character.toLowerCase(className.charAt(0)) + className.substring(1);
if (!applicationContext.containsBean(beanName))
{
Map<String, Object> annotationAttributes = ((ScannedGenericBeanDefinition) beanDefinition).getMetadata().getAnnotationAttributes(
ConditionalOnBean.class.getName());
String[] beansDependsOn = (String[]) annotationAttributes.getOrDefault("name", new String[]{});
if ((beansDependsOn.length == 1) && (beansDependsOn[0].contentEquals("yoni")) {
try {
beanRegistry.createBean(Class.forName(beanDefinition.getBeanClassName()));
} catch (ClassNotFoundException e) {
log.error("Failed to init the class : [" + beanDefinition.getBeanClassName() + "]n", e);
throw new RuntimeException(e);
}
}
}
});
}
public Rab yoni() {
Rab rab = new rab();
return rab;
}
}

相关内容

  • 没有找到相关文章

最新更新