Как переписать бины сервиса Spring по имени, используя только аннотации
Учитывая, что у меня есть Spring bean, настроенный как
@Service("myService")
public class DefaultService extends MyService {
}
и класс, использующий этот боб
public class Consumer {
@Autowired
@Qualifier("myService")
private MyService service;
...
}
Теперь я хочу, чтобы мой проект, включающий предыдущие классы, имел Consumer
другая реализация MyService
вводится Поэтому я хотел бы переписать боб myService
@Service("myService")
public class SpecializedService implements MyService {
}
в результате чего Consumer
неся сейчас экземпляр SpecializedService
вместо DefaultService
, По определению я не могу иметь два bean-компонента с одинаковым именем в контейнере Spring. Как я могу сказать весне, что определение нового сервиса перезапишет старый? Я не хочу изменять Consumer
учебный класс.
4 ответа
Либо определите служебный компонент явно
<bean id="myService" class="x.y.z.SpecializedService" />
или компонент-отсканируйте его.
В любом случае, в контексте вашего приложения избегайте явного определения DefaultService и избегайте его компонентного сканирования.
Исключить его из сканирования компонентов с помощью фильтра
<component-scan base-package="your-package">
<exclude-filter type="regex" expression="DefaultService" />
</component-scan>
Не уверен, что есть способ сделать это только с помощью аннотаций (кроме удаления аннотации @Service из DefaultService).
Связывание на основе аннотаций происходит до конфигурации на основе XML, это означает, что bean-компоненты, определенные в XML, будут перезаписывать соединения, сделанные аннотациями. Так что определение его явно в XML, как сказал Вилли, сделает всю работу
<bean id="myService" class="x.y.z.SpecializedService" />
Spring рекомендует использовать XML для bean-компонентов сервиса и репозитория, а также аннотации для bean-компонентов MVC. Он также рекомендует @Autowired без сканирования компонентов. Но аннотации в целом приветствуются, хотя они объединяют код и конфигурацию вместе (против разделения проблем).
Второе - использовать @Qualifiers("идентификатор объявленного компонента") там, где он передается.
Я знаю, уже поздно. Все еще отправляю это.
У вас должны быть разные имена для разных реализаций MyService.
Например
@Service("mySpecializedService")
public class SpecializedService implements MyService {
}
@Service("myService")
public class DefaultService extends MyService {
}
При автоматическом подключении (скажем, в Controller) вы можете использовать @Qualifier для внедрения желаемой реализации, как указано ниже.
Чтобы получить реализацию по умолчанию
@Autowired
@Qualifier("myService")
MyService myService;
Чтобы получить специализированную реализацию
@Autowired
@Qualifier("mySpecializedService")
MyService myService;