I have a interface:
public interface IBaseService {
void say();
}
And a base class:
@Service
@ConditionalOnProperty(name = "startup",havingValue = "", matchIfMissing = true)
public class BaseServiceImpl implements IBaseService {
@Override
public void say() {
System.out.println("default say");
}
}
And two child classes:
//first
@Service
@ConditionalOnProperty(name = "startup",havingValue = "1")
public class CustomService1Impl extends BaseServiceImpl{
@Override
public void say() {
System.out.println("custom 1");
}
}
//second
@Service
@ConditionalOnProperty(name = "startup",havingValue = "2")
public class CustomService2Impl extends BaseServiceImpl{
@Override
public void say() {
System.out.println("custom 2");
}
}
when i set the startup
prop in properties file
startup=
it will inject BaseServiceImpl
.
But when i use startup=1
,the error whill come out like below:
No qualifying bean of type 'com.example.service.IBaseService' available: expected single matching bean but found 2: baseServiceImpl,customService1Impl
.
i want to inject child component by set startup=1
or startup=2
.
And inject parent componet by set startup=
or not set this prop.
havingValue = ""
is tricky because it will match all values except for false
as described in docs.
One possible solution is to use @ConditionalOnMissingBean
for BaseServiceImpl
in a @Configuration
annotated class instead. We should remove both annotations from BaseServiceImpl
, and create it like this
@Configuration
public class BaseServiceConfig {
@Bean
@ConditionalOnMissingBean(IBaseService.class)
public BaseServiceImpl baseServiceImpl() {
return new BaseServiceImpl();
}
}
Any dependencies required for constructing BaseServiceImpl
can be injected using method injection.