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

时间:2015-03-11 16:05:37

标签: java spring design-patterns factory-pattern

我根据一些条件检查创建了一个工厂来决定应该返回什么样的最佳实现。

// 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);
    }

这种做法好吗?如果是的话,我怎样才能以优雅的方式获得我的服务?    我想只使用注释,没有配置。

2 个答案:

答案 0 :(得分:2)

您应该使用map而不是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)
        }
    }
}

您可以使用支持的实施预填充地图。然后,您可以按如下方式获取适当的服务实例:

    // 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);
    }

如果您不喜欢使用字符串,则可以为受支持的实现定义枚举,并将其用作地图的键。

答案 1 :(得分:1)

您无需在代码上创建列表或地图。您可以使用 GenericBeanFactoryAccessor 直接从Spring上下文中检索它。这有各种方法来检索基于名称,注释等的特定bean。您可以在这里查看javadoc。这避免了不必要的复杂性。

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