2013-10-12 3 views
6

Мы хотим иметь два реализации интерфейса для производства и разработки режима:управление два или более реализациями одного Spring интерфейса с @PROFILE

Рассмотрим интерфейса:

public interface AccountList { 
     public List<Account> getAllAccounts(String userID) ; 
} 

С двумя реализациями:

базовая реализация

@Service 
public AccountListImp1 interface AccountList { ... } 

и некоторые реализации развития

@Service 
@Profile("Dev") 
public AccountListImp2 interface AccountList { ... } 

Когда я пытаюсь использовать боб:

public class TransferToAccount{ 
    @Autowired 
    private AccountServices accountServices; 

} 

Я получаю эту ошибку:

No qualifying bean of type [AccountList] is defined: expected single matching bean but found 2: coreSabaAccountList,dummyAccountList 

В процессе разработки, мы устанавливаем spring.profiles.active в dev, как показано ниже:

<context-param> 
    <param-name>spring.profiles.active</param-name> 
    <param-value>Dev</param-value> 
</context-param> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

Я предположил, что настройка имени профиля заставит весну классифицировать бобы с разными профилями и использовать их в основе имени профиля.

Не могли бы вы дать мне знать, как я могу это решить? Я могу использовать @Primary или изменить applicationContext.xml, но я думаю, что @profile должен решить мою проблему.

ответ

8

Я думаю, что ваша проблема в том, что ваш базовый класс AccountListImp1 не помечен для любого профиля. Я думаю, что вы ожидаете, что если активный профиль не будет определен, будут выполняться beans без спецификации профиля, но когда вы определяете профиль, bean-компоненты, которые имеют такую ​​спецификацию, будут переопределять компоненты, которые реализуют один и тот же интерфейс и не имеют определения профиля. Это не работает.

При работе с активным профилем X весна запускает все бобы, которые не предназначены для какого-либо профиля и бобы, предназначенные для текущего профиля. В вашем случае это приводит к столкновению между вашими 2 реализациями.

Я думаю, что если вы хотите использовать профили, вы должны определить, по крайней мере, 2: (. Имена взяты только для примера) Dev и Prod

Теперь отметьте AccountListImp1, как Prod и AccountListImp2 в Dev:

@Service 
@Profile("Prod") 
public AccountListImp1 interface AccountList { ... } 
and some development implementation 

@Service 
@Profile("Dev") 
public AccountListImp2 interface AccountList { ... } 

Я считаю, что эта конфигурация будет работать. Удачи. Я буду рад узнать, было ли это полезно.

+1

+1 или использовать '@Profile (" default ")', профиль по умолчанию активен, если другие профили не установлены. –

+0

Он работает! Что-то выключено Тема .... Я использовал , чтобы определить весенние бобы. Один сказал, что лучше изменить базовый пакет вместо использования @profile. поэтому я могу иметь foo.bar.imp1 и foo.bar.imp2. Вы думаете, какой путь лучше? –

+1

@Alireza Fattahi, я рад узнать о вашем прогрессе. Я думаю, что использование профилей предпочтительнее, чем пакетный трюк.Трюк пакета ограничен, потому что это означает, что * все * ваши бобы должны быть дублированы для двух разных сред. Обычно это не так. Некоторые бобы являются общими. Это именно то, для чего нужны профили. – AlexR

Смежные вопросы