Manage two or more implementations of a single Spring interface With @PROFILE

We want to have two interface implementations for production and development mode:

Consider the interface:

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

With two implementations:

Base implementation

  @Service public AccountListImp1 interface AccountList { ... } 

and some development implementation

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

When I try to use a bean:

 public class TransferToAccount{ @Autowired private AccountServices accountServices; } 

I get this error:

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

During development, we set spring.profiles.active to dev , as shown below:

 <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> 

I suggested that setting the profile name will make spring categorize beans with different profiles and use them in the database by profile name.

Could you let me know how I can solve this? I can use @Primary or modify applicationContext.xml, but I think that @profile should solve my problem.

+6
source share
1 answer

I think your problem is that your base class AccountListImp1 not tagged for any profile. I think that you expect that if the active profile is not defined, beans will run without a profile specification, but when you define a profile, beans that has such a specification will override beans that implement the same interface and don't have profile definition. This does not work.

When working with the active X spring profile, all beans that are not intended for any profile and beans intended for the current profile are launched. In your case, this leads to a collision between your 2 implementations.

I think that if you want to use profiles, you should define at least 2: Dev and Prod (names are taken, for example, as.)

Now mark AccountListImp1 as Prod and AccountListImp2 as Dev :

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

I believe this configuration will work. Good luck. I will be happy to know if this was helpful.

+8
source

Source: https://habr.com/ru/post/955836/


All Articles