我想在我的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 {
...
}
这是我的主张,我使用接口而不是抽象类,但是如果你真的需要一个抽象类,你可以返回它。
@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 {
...
}
做这样的事情。我已经修改了您的抽象类DocumentProcessor
以包含文档类型。代码未经测试或编译。
这样,您可以继续引入更多处理器类型,而根本不接触处理器服务。
@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;
}
}
我建议以不同的方式解决这个问题。让我们用多角恋(未测试)替换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