简体   繁体   English

使用Spring在工厂中使用具有相同接口的注入bean的最佳方法是什么?

[英]What is the best approach to get injected beans with same interface in factory using Spring?

I created one factory to decide what best implementation should be returned, based in some conditional check. 我创建了一个工厂,根据一些条件检查来决定应返回哪种最佳实施。

// Factory
@Component
public class StoreServiceFactory {

    @Autowired
    private List<StoreService> storeServices;

    public StoreService getService(){

        if(isActiveSale){
            return storeServices.get("PublicStoreService")
        }

        return storeServices.get("PrivateStoreService")
    }
}

//Service Implementations
@Service
@Qualifier("PublicStoreService")
public class PublicStoreService implements StoreService {

    public getStoreBalanceScore(){
        Do Stuff....
    }
}

@Service
@Qualifier("PrivateStoreService")
public class PrivateStoreService implements StoreService {

    public getStoreBalanceScore(){
        Do Stuff....
    }
}


    // Controller
    @Autowired
    StoreServiceFactory storeServiceFactory;

    @Override
    public StoreData getStoreBalance(String storeId) {
        StoreService storeService = storeServiceFactory.getService();
        return simulationService.simulate(sellerId, simulation);
    }

Is this approach good? 这种方法好吗? If yes, how can i get my service from an elegant way? 如果是,我如何以一种优雅的方式获得服务? I would like to use only annotations, without configurations. 我只想使用注释,而不使用配置。

You should use a map instead of a List and pass a string parameter to the getService method. 您应该使用映射而不是List,并将字符串参数传递给getService方法。

public class StoreServiceFactory {

    @Autowired
    private Map<String,StoreService> storeServices = new HashMap<>();

    public StoreService getService(String serviceName){

        if(some condition...){
            // want to return specific implementation on storeServices map, but using @Qualifier os something else
            storeServices.get(serviceName)
        }
    }
}

You can prepopulate the map with supported implementations. 您可以使用支持的实现来预填充地图。 You can then get an appropriate service instance as follows : 然后,您可以获取适当的服务实例,如下所示:

    // Controller
    @Autowired
    StoreServiceFactory storeServiceFactory;

    @Override
    public StoreData getStoreBalance(String storeId) {
        StoreService storeService = storeServiceFactory.getService("private");//not sure but you could pass storeId as a parameter to getService
        return simulationService.simulate(sellerId, simulation);
    }

If you don't like using Strings, you can define an enum for the supported implementations and use that as the key for your map. 如果您不喜欢使用字符串,则可以为受支持的实现定义一个枚举,并将其用作映射的键​​。

You don't need to create a list or map on your code. 您无需在代码上创建列表或映射。 You can retrieve it directly from Spring context using GenericBeanFactoryAccessor . 您可以使用GenericBeanFactoryAccessor从Spring上下文直接检索它。 This has various method to retrieve a specific bean like based on name, annotation etc. You can take a look at javadoc here. 这有多种方法来检索特定的bean,例如基于名称,注释等。您可以在此处查看javadoc。 This avoids unnecessary complexity. 这避免了不必要的复杂性。

http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/beans/factory/generic/GenericBeanFactoryAccessor.html http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/beans/factory/generic/GenericBeanFactoryAccessor.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM