Как переписать бины сервиса 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;
Другие вопросы по тегам