在某些bean上,我使用ConditionalOnBean (示例中的a和b )。在应用程序启动时,以它为条件的bean不存在。因此,注释(ConditionalOnBean)下的bean (示例中的ConditionalOnBean)没有初始化,也没有被Spring处理。在运行应用程序的过程中,bean被动态地添加到上下文中(参见示例中的addYoni )。为了初始化现在传递条件的bean(示例中是a和b ),我需要告诉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;
}
}发布于 2022-07-15 10:03:48
最后,我找到了一种方法。它需要使用注释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;
}
}https://stackoverflow.com/questions/72977235
复制相似问题