我正在努力实施某些行动的责任链。从高层次开始,有服务,每个服务都有一系列行动被执行。目前我有一组动作bean,当Service I想知道是否有任何方法我可以利用map实现这一点并仍然进行自动注入时执行。
答案 0 :(得分:0)
如果在应用程序生命周期中将产品设置为一次,则可以使用弹簧配置文件。为产品1和产品2创建单独的配置文件,并使用@Profile注释注释您的Service类。在这种情况下,您可以使用每个配置文件的不同值填充操作列表。
如果可以在运行时动态更改Product,则可以通过实现InitializngBean和BeanNameAware接口来声明Product bean。 BeanNameAware允许您检查配置是针对产品1还是产品2,而InitializingBean使您有机会根据bean名称以不同方式设置列表。
答案 1 :(得分:0)
是否可以实现动作bean 1,2,3获取的灵活性 如果它是产品1,则添加到ServiceA执行链中,但仅限于 如果是,则将操作bean 1,3添加到链中以执行ServiceA 产品2?
此方法的主要问题是自动装配在应用程序启动时发生,而不是在服务上调用execute
时发生。如果需要在运行时处理这两种类型,则需要自动装配所有操作。
您可以采取哪些措施来避免在服务类中使用if / else时,将决定哪些操作适用于产品的责任转移到操作本身。
这样的事情:
public enum ProductType {
PROD1, PROD2
}
public interface Product {
public ProductType getType();
}
public interface Action {
public boolean execute(Product p);
public ProductType[] supportedTypes();
}
@Component
@Order(1)
public class Action1 implements Action {
public boolean execute(Product p) {
// do stuff
}
public ProductType[] supportedTypes() {
return ProductType.values();
}
}
@Component
@Order(2)
public class Action2 implements Action {
public boolean execute(Product p) {
// do stuff
}
public ProductType[] supportedTypes() {
return new ProductType[] {PROD2};
}
}
@Service
public class ServiceA {
private Map<ProductType, List<Action>> actionMap = new HashMap<>();
@Override
public boolean execute(Product product) {
List<Action> actions = actionMap.get(product.getType());
// call each action
}
@Autowired
public void setActions(List<Action> actions) {
for (Action action : actions) {
for (ProductType type : action.supportedTypes()) {
if (!actionMap.containsKey(type)) {
actionMap.put(type, new ArrayList<>());
}
actionMap.get(type).add(action);
}
}
}
}
答案 2 :(得分:0)
我认为您对自动装配有很多期待。在这种情况下,我会补充自动装配,这实际上是使用配置文件跟踪代码注释中的静态配置。使用spring beans xml文件将自定义链放在一起以用于特定上下文。好处是,您在XML文件中连接的所有内容都可以从注释中自动连接。春天非常善于让你混淆隐喻。