So, I have the following application:
@SpringBootApplication
public class AutonullApplication {
public static void main(String[] args) {
SpringApplication.run(AutonullApplication.class, args);
}
@Bean
First first() {
return null;
}
public class First {
}
@Service
public class Second {
private final First first;
public Second(First first) {
this.first = first;
}
@PostConstruct
public void print() {
System.out.println("First = " + first);
}
}
}
which tries to inject a bean of type First
into a service of type Second
. But the bean has a value of null
. This code works fine in Spring Boot 1.5.10 (and so Spring 4), but fails in Spring Boot 2.0 (and Spring 5):
Description:
Parameter 1 of constructor in eu.plumbr.autonull.AutonullApplication$Second required a bean of type 'eu.plumbr.autonull.AutonullApplication$First' that could not be found.
Is anybody aware of any mention of such change in the official documentation?
Yes, this is a breaking change in Spring Framework 5. Arguably, such setup is weird and we wanted to tighten those rules a little bit.
If you request to inject First
and you provide null
, then it's more consistent to consider that bean isn't provided. You can then query the context for the presence of First
. @spencergibb already explained how you can use Optional
, or you can use ObjectProvider<First>
as an injection point:
@Service
public class Second {
private final First first;
public Second(ObjectProvider<First> first) {
this.first = first.getIfAvailable(); // return null
}
}