我试图实现一个Spring条件,只有在某个类没有其他bean的情况下,它才会加载我的bean。所需的行为类似于"@ConditionalOnMissingBean“,但不使用spring。
我正在使用SpringVersion5.3.13。
这有可能吗?谢谢。
发布于 2021-12-14 07:27:38
我通过研究spring引导源代码找到了一个解决方案。ConditionalOnBean只对在配置(bean方法)中定义的bean工作。对于@ConditionalOnBean,spring java doc也推荐这样做。
条件只能与应用程序上下文处理过的bean定义相匹配,因此强烈建议只在自动配置类上使用该条件。如果候选bean可能是由另一个自动配置创建的,请确保使用此条件的bean随后运行。
这里是我想出的解决方案的基础,这可能会得到改进,但基本操作很好。
条件:
@Slf4j
class MissingBeanCondition implements ConfigurationCondition {
@Override
public ConfigurationPhase getConfigurationPhase() {
return ConfigurationPhase.REGISTER_BEAN;
}
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
var targetBeanType = metadata.getAnnotations()
.get(ConditionalOnMissingBean.class)
.getValue("value", Class.class)
// TODO throw a more informative error
.orElseThrow(() -> new RuntimeException("Failed to evaluate MissingBeanCondition"));
try {
context.getBeanFactory().getBean(targetBeanType);
} catch (NoSuchBeanDefinitionException e) {
return true;
}
return false;
}
}
注释:
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Conditional(MissingBeanCondition.class)
public @interface ConditionalOnMissingBean {
Class<?> value();
}
用法示例:
@Bean
@Singleton
@ConditionalOnMissingBean(Provider.class)
public Provider myClass() {
return new DefaultProvider();
}
https://stackoverflow.com/questions/70340488
复制