How do I extend a named bean when using a @Qualifier
specified bean injection point?
I have project 1 consisting of 3 spring beans:
@Component("bean1")
public class Bean1 implements Bean {
}
@Component("bean2")
public class Bean2 implements Bean {
}
@Component("bean3")
public class Bean3 {
private Bean bean;
public void setBean(@Qualifier("bean1") final Bean bean) {
this.bean = bean;
}
}
This project is bundled into a jar and included as a dependency on my 2nd project:
@Component("bean1")
@Primary
public class Bean1Child extends Bean1 {
}
What I want to happen is for the bean, Bean1Child
, to be injected into Bean3
's setter method. Unfortunatly I am receiving an error.
org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'bean1' for bean class [Bean1Child] conflicts with existing, non-compatible bean definition of same name and class [Bean1]
I needed to use @Qualifier
so that Bean2
is not injected into Bean3
Using the @Primary
annotation did not help. How can I have Bean1Child
injected into Bean3
when running from my 2nd project?
If this is possible, you can change the way the beans are created by removing the @Component
annotations:
In the first project, the BeanChild3
would be refactored to get the bean
in the constructor
public class Bean3 {
private final Bean bean;
public Bean3(final Bean bean) {
this.bean = bean;
}
}
Then we can create the beans in a BeansConfig
class
@Configuration
class BeansConfig {
@ConditionalOnMissingBean
@Bean("bean1")
Bean bean1(){
return new Bean1();
}
@Bean("bean2")
Bean bean2(){
return new Bean2();
}
@Bean("bean3")
Bean bean3(@Autowired @Qualifier("bean1") Bean){
return new Bean3(bean);
}
}
The @ConditionalOnMissingBean
allows us to provide another bean with the same name to be used instead. If no such bean exists, then the default one would be used.
You will then need to create a beanChild1
bean in your second project and it should be picked up.
@Bean("bean1")
Bean bean1(){
return new Bean1Child();
}