简体   繁体   English

在条件类的子类中春季注入bean

[英]Spring injecting bean in sub classes of condition class

I have a component like this 我有一个这样的组件

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

    @Override
    public void afterPropertiesSet() throws Exception {

        System.out.println();

    }
}

I also have Condition class like this: 我也有这样的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;
        }
    }

I can't autowire any Spring bean in ConditionExample class. 我不能自动连接ConditionExample类中的任何Spring bean。 It remains null. 它保持为空。 I tried @Component on top of ConditionExample but it won't work. 我在ConditionExample之上尝试了@Component,但是它不起作用。 I need to query db with my repository class in matches method and decide whether to create or not create the bean. 我需要使用matchs方法中的存储库类查询db并决定是否创建Bean。 How do I accomplish that? 我该怎么做?

You cannot inject bean to your Condition class: 您不能将bean注入到Condition类中:

Here is the document with highlighted. 这是突出显示的文档

Conditions must follow the same restrictions as BeanFactoryPostProcessor and take care to never interact with bean instances . 条件必须遵循与BeanFactoryPostProcessor相同的限制,并注意不要与bean实例进行交互 For more fine-grained control of conditions that interact with @Configuration beans consider the ConfigurationCondition interface. 要更精细地控制与@Configuration Bean交互的条件,请考虑ConfigurationCondition接口。

To solve your issue, I think you have to change where you store your condition or using plain javacode to create connection to database and check the condition 为了解决您的问题,我认为您必须更改条件的存储位置或使用简单的Javacode创建与数据库的连接并检查条件

I don't think it is possible to do. 我认为这是不可能的。 Because @Conditional annotations are processed way to early in the component scan during which your repository or any other classes are not loaded. 因为@Conditional批注是在组件扫描的早期进行处理的,在此期间不会加载存储库或任何其他类。

You can Autowire ApplicationContext class in Condition class and put a debug point in your matches method and see the application context bean definition map. 您可以在Condition类中自动装配ApplicationContext类,并将调试点放入matchs方法中,并查看应用程序上下文Bean定义图。 You don't have many classes loaded(hardly few). 您没有加载很多类(几乎没有)。

One possible solution is, You can write a bean with your repository class autowired. 一种可能的解决方案是,您可以使用自动装配的存储库类编写一个Bean。 In which in @PostContruct method you can do a database query and based on the result you can register other bean(which you want to load conditionally) to application context. 在其中@PostContruct方法中,您可以执行数据库查询,并根据结果可以将其他bean(要有条件地加载)注册到应用程序上下文中。

Something like this 像这样

@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(...)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM