Java EE中抽象类FileHandler的通用文件处理器注入方案问询
解决方案
1. 自定义限定符关联文件类型
先创建一个自定义限定符注解,用来标记每个处理器对应的文件类型:
@Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.FIELD}) public @interface FileType { String value(); }
给每个处理器类加上该限定符,指定对应的文件类型:
@FileType("xml") public class XmlHandler extends FileHandler { // 实现handle方法 } @FileType("csv") public class CsvHandler extends FileHandler { // 实现handle方法 }
2. 用@Any + Instance实现动态查找
注入Instance<FileHandler>并结合自定义限定符,就能根据fileType动态获取对应处理器,无需硬编码具体实现类:
@Inject @Any private Instance<FileHandler> fileHandlers; public void method(String fileType) { // 构建限定符实例,匹配对应处理器 FileType qualifier = new FileTypeQualifier(fileType); Instance<FileHandler> handlerInstance = fileHandlers.select(qualifier); if (!handlerInstance.isUnsatisfied() && !handlerInstance.isAmbiguous()) { handlerInstance.get().handle(); } else { // 处理无匹配或多匹配情况,比如抛出异常 throw new IllegalArgumentException("No valid handler for file type: " + fileType); } } // 辅助类:生成限定符注解实例 private static class FileTypeQualifier extends AnnotationLiteral<FileType> implements FileType { private final String type; public FileTypeQualifier(String type) { this.type = type; } @Override public String value() { return type; } }
3. 优化:提前初始化处理器映射(可选)
如果想避免每次查找的开销,可以在启动时将所有处理器加载到Map中,后续直接通过fileType获取:
private Map<String, FileHandler> handlerMap; @Inject public YourService(@Any Instance<FileHandler> fileHandlers) { handlerMap = new HashMap<>(); for (FileHandler handler : fileHandlers) { FileType fileTypeAnnotation = handler.getClass().getAnnotation(FileType.class); if (fileTypeAnnotation != null) { handlerMap.put(fileTypeAnnotation.value(), handler); } } } public void method(String fileType) { FileHandler handler = handlerMap.get(fileType); if (handler != null) { handler.handle(); } else { throw new IllegalArgumentException("No valid handler for file type: " + fileType); } }
关于Instance使用的疑问澄清
你提到的「使用Instance时仍需传入目标实现类的类文件」是误解。通过自定义限定符,我们完全可以基于文件类型字符串匹配对应处理器,无需在代码中引用具体实现类(比如XmlHandler、CsvHandler)。后续新增文件类型时,只需新增继承FileHandler的类并添加@FileType注解,无需修改分发逻辑,完全符合开闭原则。
内容的提问来源于stack exchange,提问作者Thomas E
相关产品推荐
相关产品推荐

