Given I have a Spring bean configured as
@Service("myService")
public class DefaultService extends MyService {
}
and a class using this bean
public class Consumer {
@Autowired
@Qualifier("myService")
private MyService service;
...
}
I now want my project, that includes the preceding classes, to have Consumer
another implementation of MyService
being injected. Therefore I would like to overwrite the bean myService
@Service("myService")
public class SpecializedService implements MyService {
}
resulting in Consumer
carrying now an instance of SpecializedService
instead of DefaultService
. By definition I cannot have two beans with the same name in the Spring container. How can I tell spring, that the definition of the new service shall overwrite the older one? I don't want to modify the Consumer
class.
Either define the service bean explicitly
<bean id="myService" class="x.y.z.SpecializedService" />
or component-scan it.
In either event, in your application context, avoid explicitly defining DefaultService and avoid component-scanning it.
Exclude it from component-scan by using a filter
<component-scan base-package="your-package">
<exclude-filter type="regex" expression="DefaultService" />
</component-scan>
Not sure if there is a way to do it with only annotations (other than removing the @Service annotation from DefaultService).
Annotation based wiring happens before the XML based configuration, that means beans defined in XML will
overwrite those wiring done by Annotations.
So defining it explicitely in XML, like Willie has said will do the work
<bean id="myService" class="x.y.z.SpecializedService" />
Spring recommends using XML for service and repository beans and annotation for MVC beans. It also recommends @Autowired without component scanning. But Annotation are in general encouraged, although it merges code and configuration together (against seperation of concerns).
Second thing is to use @Qualifiers("id of declared bean") where it is being passed.
I know , its late . Still posting it.
You should have different names for different implementations of MyService.
For instance
@Service("mySpecializedService")
public class SpecializedService implements MyService {
}
@Service("myService")
public class DefaultService extends MyService {
}
While autowiring them ( say in Controller) , you may use @Qualifier to inject desired implementation as mentioned below.
To get default implementation
@Autowired
@Qualifier("myService")
MyService myService;
To get specialized implementation
@Autowired
@Qualifier("mySpecializedService")
MyService myService;