实现一 使用依赖注入的方式

定义接口

1
2
3
4
public interface FileHandler{
void handle(String filePath, Map<String, Object> data);
String getHandlerName();
}

定义常量类

1
2
3
4
public interface HandlerType{
String JAVA = "java";
String POM = "pom";
}

实现接口

1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
@Slf4j
public class JavaFileHandler implements FileHandler{
@Override
public void handle(String filePath, Map<String, Object> data){
// doSomething...
}

@Override
public String getHandlerName(){
return HandlerType.JAVA;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
@Slf4j
public class PomFileHandler implements FileHandler{
@Override
public void handle(String filePath, Map<String, Object> data){
// doSomething...
}

@Override
public String getHandlerName(){
return HandlerType.POM;
}
}

定义工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Component
public class FileHandlerFactory{
private Map<String, FileHandler> fileHandlerMap = new HashMap<>();

public FileHandler getFileHandler(String handlerName){
return this.fileHandlerMap.get(handlerName);
}

@Autowired
private void setFileHandlers(List<FileHandler> fileHandlers){
if(CollectionUtils.isEmpty(fileHandlers)){
throw new ServiceException("file handler is null");
}

fileHandlers.forEach(handler -> this.fileHandlerMap.put(handler.getHandlerName(), handler));
}
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Component
@Slf4j
public class FileUtil{
@Autowired
private FileHandlerFactory fileHandlerFactory;

public void handleFiles(String filePath, Map<String, Object> data){
if(javaCondition){
// 需要处理java文件
fileHandlerFactory.getFileHandler(HandlerType.JAVA).handler(filePath, data);
}
if(pomCondition){
// 需要处理pom文件
fileHandlerFactory.getFileHandler(HandlerType.POM).handler(filePath, data);
}
// ...
}
}

注:这里的使用可以优化,利用map来扭转条件,具体实现见记一次用Map优化if/else的过程

实现二 使用ApplicationContext上下文

定义接口

1
2
3
public interface FileProcessor{
void handle(String filePath, Map<String, Object> data);
}

定义常量类

1
2
3
4
public interface ProcessorType{
String JAVA = "java";
String POM = "pom";
}

实现接口

1
2
3
4
5
6
7
8
9
@Component
public class JavaFileProcessor implements FileProcessor{

@Override
public void handle(String filePath, Map<String, Object> data){
// doSomething
}

}

定义工厂类

1
2
3
4
5
6
public class FileProcessorFactory{
public static FileProcessor getFileProcessor(String fileProcessorType){
return SpringContextHolder
.getBean(fileProcessorType + FileProcessor.class.getSimpleName(), FileProcessor.class)
}
}

定义SpringContextHolder类

1
2
3
4
5
6
7
8
9
10
11
12
13
@Service
@Slf4j
public class SpringContextHolder implements ApplicationContextAware{
private static ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException{
SpringContextHolder.applicationContext = applicationContext;
}

// 省略getBean方法...
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Component
@Slf4j
public class FileUtil{

public void handleFiles(String filePath, Map<String, Object> data){
FileProcessor fileProcessor = null;
if(javaCondition){
// 需要处理java文件
fileProcessor = FileProcessorFactory.getFileProcessor(ProcessorType.JAVA);
fileProcessor.handle(filePath,data);
}
if(pomCondition){
// 需要处理pom文件
fileProcessor = FileProcessorFactory.getFileProcessor(ProcessorType.POM);
fileProcessor.handle(filePath,data);
}
// ...
}
}

说明

  1. 这里定义的常量类,还可以设计成在配置文件中配置,在java中通过@Value进行绑定,这样在采用不同实现的时候只需修改配置文件即可,无需更改代码。
  2. getBean()时注意大小写问题
    • 如果类第一个字母大写第二个小写,那么首字母小写获取bean
    • 如果类第一个和第二个字母都是大写的,那个获取bean首字母要大写

Read More

[1] SpringContextHolder静态持有SpringContext的引用
[2] 使用SpringContextHolder获取bean实例
[3] 自定义SpringContextHolder获取bean实例(一)
[4] Spring getBean 首字母大小写问题
[5] 关于springContext.getBean(“***”)首字母小写
[6] 未被Spring托管的Bean如何获取Spring管理的Bean