sarah
sarah

Reputation: 620

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:

 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. It remains null. I tried @Component on top of ConditionExample but it won't work. I need to query db with my repository class in matches method and decide whether to create or not create the bean. How do I accomplish that?

Upvotes: 0

Views: 1195

Answers (2)

pvpkiran
pvpkiran

Reputation: 27078

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.

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. You don't have many classes loaded(hardly few).

One possible solution is, You can write a bean with your repository class autowired. 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.

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

Upvotes: 1

Mạnh Quyết Nguyễn
Mạnh Quyết Nguyễn

Reputation: 18235

You cannot inject bean to your Condition class:

Here is the document with highlighted.

Conditions must follow the same restrictions as BeanFactoryPostProcessor and take care to never interact with bean instances. For more fine-grained control of conditions that interact with @Configuration beans consider the ConfigurationCondition interface.

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

Upvotes: 1

Related Questions