gpt4 book ai didi

java - 带有命令模式的 spring beans 映射

转载 作者:行者123 更新时间:2023-11-29 04:11:51 25 4
gpt4 key购买 nike

我得到了具有不同实现的 ProductHandler 类,例如 ABCProductHandlerDEFProductHandler 等。它们是从 ProductServiceImpl 类使用命令模式,如图所示 here .

ProductServiceImpl 类:

@Service
public class ProductServiceImpl implements ProductService {

private Map<ProductType,ProductHandler> productHandlersMap =
new EnumMap<>(ProductType.class);

private ABCProductHandler abcProductHandler;

private DEFProductHandler defProductHandler;

//....10 other product handlers goes here

@Autowired
public ProductServiceImpl(ABCProductHandler abcProductHandler,
DEFProductHandler defProductHandler, .....) {
this.abcProductHandler = abcProductHandler;
this.defProductHandler = defProductHandler;
//....10 other product handlers goes here
}

@PostConstruct()
public void init() {
productHandlersMap.put(ProductType.ABC, abcProductHandler);
productHandlersMap.put(ProductType.DEF, defProductHandler);
//....10 other product handlers goes here
}

@Override
public ProductDetails calculateProductPrice(ProductType productType) {
productHandlersMap.get(productType).calculate();
//..some otehr code goes here
return productDetails;
}
}

但是,我对上面的 ProductServiceImpl 类不满意,因为有很多使用样板代码的 productHandlersMap.put 调用。

现在,我的问题是有什么方法可以轻松加载 productHandlersMap

@Service
public class ProductServiceImpl implements ProductService {

private Map<ProductType,ProductHandler> productHandlersMap =
new EnumMap<>(ProductType.class);

@PostConstruct()
public void init() {
//How to laod productHandlersMap easily with
// different ProductHandler types here?
}

@Override
public ProductDetails calculateProductPrice(ProductType productType) {
productHandlersMap.get(productType).calculate();
//..some other code goes here
return productDetails;
}
}

最佳答案

Spring 可以 Autowiring 实现接口(interface)的 bean 的不同实现 IMap<String, I> 类型的属性自动,其中键是 bean 的名称,值是 bean 实例。因为您已经有一个枚举来定位每个 ProductHandler实现,您可以利用它:

public enum ProductType {
ABC(ProductType.ABC_BEAN_NAME),
DEF(ProductType.DEF_BEAN_NAME);

public static final String ABC_BEAN_NAME = "abcProductHandler";
public static final String DEF_BEAN_NAME = "defProductHandler";

private String beanName;

ProductType(String beanName) { this.beanName = beanName; }

public String beanName() { return beanName; }
}

然后,定义不同的 ProductHandler@Configuration 中实现工厂类或通过 @Service@Component注释:

@Service(ProductType.ABC_BEAN_NAME)
public class ABCProductHandler implements ProductHandler {

// ...
}

@Service(ProductType.DEF_BEAN_NAME)
public class DEFProductHandler implements ProductHandler {

// ...
}

现在,在您的 ProductServiceImpl 中bean,只需 Autowiring 一个 Map<String, ProductHandler> :

@Service
public class ProductServiceImpl implements ProductService {

private final Map<String, ProductHandler> productHandlersMap;

@Autowired
public ProductServiceImpl(Map<String, ProductHandler> productHandlersMap) {
this.productHandlersMap = productHandlersMap;
}

@Override
public ProductDetails calculateProductPrice(ProductType productType) {
productHandlersMap.get(productType.beanName()).calculate();
//..some otehr code goes here
return productDetails;
}
}

这样,您就可以让 Spring 完成所有的注入(inject)工作,甚至不需要使用 @PostConstruct。方法。

注意 productType.beanName() 的使用在calculateProductPrice里面方法。这可确保您使用正确的 bean 来计算价格。

关于java - 带有命令模式的 spring beans 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54635918/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com