Spring在条件类的子类中注入bean

时间:2018-06-08 10:15:29

标签: java spring spring-boot dependency-injection spring-data

我有这样的组件

@Component
@Conditional(ConditionExample.class)
public class ScheduledExample implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {

        System.out.println();

    }
}

我也有这样的Condition类:

 public class ConditionExample implements Condition {

        private ParameterRepository parameterRepository; // it is a spring data repository

        @Autowired
        public void setParameterRepository(ParameterRepository parameterRepository) {
            this.parameterRepository= parameterRepository;
        }

        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            //query db with parameterRepository and decide
            return false;
        }
    }

我无法在ConditionExample类中自动装配任何Spring bean。它仍然是空的。我在ConditionExample上尝试了@Component,但它不起作用。 我需要在matches方法中使用我的存储库类查询db,并决定是否创建bean。我该如何实现?

2 个答案:

答案 0 :(得分:1)

您不能将bean注入Condition类:

以下是突出显示的document

  

条件必须遵循与BeanFactoryPostProcessor相同的限制,并且注意永远不要与bean实例交互。要更好地控制与@Configuration bean交互的条件,请考虑ConfigurationCondition接口。

要解决您的问题,我认为您必须更改存储条件的位置或使用普通的javacode创建与数据库的连接并检查条件

答案 1 :(得分:1)

我认为不可能这样做。因为@Conditional注释是在组件扫描的早期处理的,在此期间您的存储库或任何其他类未加载。

您可以在Condition类中自动装配ApplicationContext类,并在匹配方法中放置一个调试点,并查看应用程序上下文bean定义映射。你没有加载很多课程(很少)。

一种可能的解决方案是,您可以使用自动装配的存储库类编写bean。在@PostContruct方法中,您可以执行数据库查询,并根据结果将其他bean(您要有条件地加载)注册到应用程序上下文。

像这样的东西

@Component
public class SomeBean {

    private ParameterRepository parameterRepository; // it is a spring data repository

    private GenericWebApplicationContext context;

    @Autowired
    public void setParameterRepository(ParameterRepository parameterRepository, GenericWebApplicationContext context) {
        this.parameterRepository= parameterRepository;
        this.context = context
    }

    @PostConstruct
    public void someMethod() {
        //query db with parameterRepository and decide
        //context.registerBeanDefinition(...)
    }
}