首页 > 解决方案 > 在 BeanDefinitionRegistry 中注册后如何阻止 bean 实例化

问题描述

在 BeanDefinitionRegistry 中注册后,我需要从实例化中取消注册几个 bean。我需要在某些情况下这样做。

如果我写这样的代码

@Component
public class DomainConfig implements BeanDefinitionRegistryPostProcessor {

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
    beanDefinitionRegistry.removeBeanDefinition("createBlahExporter");
    beanDefinitionRegistry.removeBeanDefinition("createBlahDataSource");
    beanDefinitionRegistry.removeBeanDefinition("createBlahMonitorSettings");
    beanDefinitionRegistry.removeBeanDefinition(("com.blah.BlahConfiguration));
}
}

我收到以下错误:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field blahDataExporter in com.blah.BlahConfiguration required a bean of type 
'com.blah.export.Exporter' that could not be found.

The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)

The following candidates were found but could not be injected:
- Bean method 'createProviderDumpExporter' in 'ProviderDumperConfig' not loaded because 
@ConditionalOnProperty (providers.dump.local.enabled=true) found different value in property 
'providers.dump.local.enabled'


Action:

Consider revisiting the entries above or defining a bean of type 'com.harman.inca.export.Exporter' in 
your configuration.

即使从这里移走,也有人,在某处拿着注册的名字。如何从已注册的 bean 集中删除 bean。

标签: springspring-bean

解决方案


您没有指定什么是 ConfigFactory,但可以考虑添加您自己的 Conditional 实现。

自定义条件可以从这个配置工厂读取定义,并且绑定到这个自定义条件谓词的注释可以放在您计划“取消注册”的 bean 上。使用这种方法,它们将不会在应用程序上下文中注册,因此您无需取消注册它们。

有很多关于如何实现这些自定义条件的教程:

从原理上讲,您应该:

  1. 实现条件的逻辑
class OnConfigFactoryCondition implements Condition {

  @Override
    public boolean matches(
        ConditionContext context, 
        AnnotatedTypeMetadata metadata) {
      // analyze the value from ConfigFactory whatever it is
      Return true /false
    }
}
  1. 创建一个绑定到您的条件的条件注释:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(OnConfigFactoryCondition.class)
public @interface ConditionalOnConfigFactory {
  ...
}

然后,您可以将此注释放在@Component定义旁边,或者@Bean如果您使用的是 Java Config


推荐阅读