Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot ConditionalOnBean annotation

There are spring boot 2.0.2 configuration

@Configuration
public class ApiConfig {

    @Bean
    @Profile("!tests")
    @ConditionalOnProperty(name = "enabled", havingValue = "true")
    public MyService service() {
        return new MyServiceImpl();
    }

}

... and some controller which should be created and added to application context only if MyService bean is initialized.

@RestController
@ConditionalOnBean(MyService.class)
public class MyController {
   @Autowired
   private MyService service;
}

It works Ok. But occasionally spring boot skips MyController creating. According to the logs MyService is created, but after any other beans(including all controllers), at the end.

Why boot does not process @Configuration beans prior to @RestController? Thanks.

like image 841
r.r Avatar asked Jun 26 '26 23:06

r.r


1 Answers

Why boot does not process @Configuration beans prior to @Controller? Thanks.

Because Spring doesn't guarantee that.
As well as @ConditionalOnBean warns about this kind of issue in this specification :

The condition can only match the bean definitions that have been processed by the application context so far and, as such, it is strongly recommended to use this condition on auto-configuration classes only. If a candidate bean may be created by another auto-configuration, make sure that the one using this condition runs after.

And you don't use the annotation in an auto-configuration class. You indeed specified it in a class annotated with @RestController.

I think that to achieve your requirement you should move the @RestController bean declaration in a @Configuration class that's imported via an EnableAutoConfiguration entry in spring.factories.

like image 150
davidxxx Avatar answered Jun 28 '26 12:06

davidxxx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!