When using the Spring Java Config developers often follow the principle of code to the interface not the implementation and thus make the return type of a @Bean
method the interface. This can lead to subtle bugs, if the actual class actually implements more interfaces that are used elsewhere.
Spring uses the method return type to resolve dependencies between beans. When a bean is initialized it will update its knowledge of the bean by looking at the actual instance, so the code that only returns the interface might actually work if by chance the beans are initialized in the right order. However, the order is not strongly guaranteed and can change due to unrelated changes, leading to hard to debug bugs.
As there is no real downside, aside from style and habit, to declaring the actual type as return type it should be the default.
Noncompliant Code:
@Configuration
public class Config {
@Bean
MyInterface service() { // Noncompliant code
return new MyServiceImpl();
}
}
Compliant Code:
@Configuration
public class Config {
@Bean
MyServiceImpl service() { // compliant code
return new MyServiceImpl();
}
}
type: Bug