Description
I am working on upgrading some Spring 5 code to Spring 6. This code does have some @Bean
factory methods that can return null
, and I've encountered some autowiring failures. While I understand this should be avoided, the following behavior seemed a bit unintuitive to me.
Given the following minimal example (Spring 6.2.6):
package example.example;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
public class ExampleApplication {
public static class Dependency { }
@Configuration
public static class TestConfiguration {
@Nullable
@Bean
Dependency d() {
return null;
}
// org.springframework.beans.factory.NoSuchBeanDefinitionException
@Bean
public Object test1(Dependency d) {
return new Object();
}
// Injects null
@Bean
public Object test2(@Nullable Dependency d) {
return new Object();
}
// Injects null
@Bean
public Object test3(Dependency x) {
return new Object();
}
}
public static void main(String[] args) {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
context.register(TestConfiguration.class);
context.refresh();
}
}
}
test1()
, in which the injected parameter is retrieved by name, throws NoSuchBeanDefinitionException
(note: previously in Spring 5.x this would inject the parameter as null
).
test2()
is simply to demonstrate that annotating the parameter as @Nullable
is a possible solution.
test3()
in which the injected parameter is retrieved by type, continues to inject null
without issue.
Therefore, I ran into wiring failures at injection points where parameter names happened to match the null
bean name, but not where the parameter name differed and there was still apparently a null
candidate bean retrieved by type.
My expectation would be that test1()
and test3()
would either both succeed or both fail in the same way.