我想在Spring应用程序中将此类型的服务类用作“工厂”,以响应提供的枚举值返回DocumentProcessor的正确实现。
之所以这样做,是因为我想将每个处理器本身设置为组件,并利用自动装配的优势,而不是仅在需要每个处理器时创建新实例。
在其他任何地方我都没有真正看到它完成-有人可以告诉我这是否是个坏主意吗?
所有“ TypeXYZDocumentProcessor”类都是抽象“ DocumentProcessor”基类的扩展。
@Service
public class DocumentProcessorService {
@Autowired
TypeXDocumentProcessor typeXDocumentProcessor;
@Autowired
TypeYDocumentProcessor typeYDocumentProcessor;
@Autowired
TypeZDocumentProcessor typeZDocumentProcessor;
public DocumentProcessor getDocumentProcessor(DocumentType docType) {
switch (docType) {
case TYPE_X:
return typeXDocumentProcessor;
case TYPE_Y:
return typeYDocumentProcessor;
case TYPE_Z:
return typeZDocumentProcessor;
default:
return null;
}
}
}
@Component
public class TypeXDocumentProcessor extends DocumentProcessor {
...
}
public abstract class DocumentProcessor {
...
}
答案 0 :(得分:2)
这是我的命题,我使用了Interface而不是抽象类,但是如果您确实需要抽象类,则可以在其上返回。
@Service
public class DocumentProcessorService {
@Autowired
// you can add here for examlpe a @Qualifier("typeXDocumentProcessor"),
// then name your variable whatever you want.
DocumentProcessor typeXDocumentProcessor;
@Autowired
DocumentProcessor typeYDocumentProcessor;
@Autowired
DocumentProcessor typeZDocumentProcessor;
public DocumentProcessor getDocumentProcessor(DocumentType docType) {
switch (docType) {
case TYPE_X:
return typeXDocumentProcessor;
case TYPE_Y:
return typeYDocumentProcessor;
case TYPE_Z:
return typeZDocumentProcessor;
default:
return null;
}
}
}
@Component
public class TypeXDocumentProcessor implements DocumentProcessor {
...
}
@Component
public class TypeYDocumentProcessor implements DocumentProcessor {
...
}
@Component
public class TypeZDocumentProcessor implements DocumentProcessor {
...
}
public interface class DocumentProcessor {
...
}
答案 1 :(得分:1)
您也可以做这样的事情。我已经修改了您的抽象类DocumentProcessor
以包括DocumentType。
代码未经测试或编译。
这样,您可以继续引入更多的处理器类型,而完全不涉及处理器服务。
@Service
public class DocumentProcessorService {
@Autowired
List<DocumentProcessor> documentProcessors;
public DocumentProcessor getDocumentProcessor(DocumentType docType) {
return documentProcessors.stream().filter(e -> e.getDocType().equals(docType)).findFirst().get();
}
}
@Component
public class TypeXDocumentProcessor extends DocumentProcessor {
public TypeXDocumentProcessor() {
super(TYPE_X);
}
}
// More Types...
public abstract class DocumentProcessor {
...
DocumentType docType;
public DocumentProcessor(DocumentType docType) {
this.docType = docType;
}
DocumentType getDocType() {
return docType;
}
}
答案 2 :(得分:0)
我建议以另一种方式进行此操作。让我们用多态性(未经测试)替换switch
或if
块:
public enum DocumentType {
TYPE_X("typeXDocumentProcessor"),
TYPE_y("typeYDocumentProcessor");
private DocumentProcessor processor;
private final String beanName;
DocumentType (String beanName){
this.beanName = beanName;
}
public String process(){
return processor.process();
}
@Component
public static class DocumentTypeInjector {
@Autowired
private ApplicationContext context;
@PostConstruct
public void postConstruct() {
for (DocumentType dt : EnumSet.allOf(DocumentType.class))
dt.processor = context.getBean(dt.beanName)
}
}
}
然后您的服务完全不需要getDocumentProcessor
方法。例如,您只有一个process
方法,调用当前枚举实例的process