() {
@Override
public String getKey(CustomerPropertiesTypeEnum enumValue) {
return enumValue.code;
}
});
public static CustomerPropertiesTypeEnum getByCode(String code) {
return CODE_HELPER.find(code);
}
}
```
上述代码中的自定义了`EnumFindHelper`来实现通过code查找枚举对象,该操作类的实现可以参考我的相关的博客TODO
上面的代码其实使用的就是简化版本地策略模式,只不过还没有相对应的策略处理模型,接下来我们就来封装策略处理模型代码。
按照上面的思路,我们需要在系统启动后,组装对应的数据接口,为什么需要等到系统启动之后呢?由于该项目是SpringBoot框架我们的自定义属性处理器都是注入到Spring的Bean容器中的,我们需要再从Bean容器中获取到,然后组装我们需要的数据接口
```java
/**
* Copyright © 2018 五月工作室. All rights reserved.
*
* @Project: stuff
* @ClassName: CustomPropertiesTypeBeanInitialization
* @Package: com.amos.stuff.proxyandspring.biz.util
* @author: zhuqb
* @Description: 自定义属性处理器和自定义属性类型数据初始化
*
* 通过自定义属性处理接口来获取所有的自定义属性处理器
* 组装每个自定义属性处理器对应的类型
*
* 以Map结构来存储
*
* 这里之所以使用枚举对象是为了解决hash冲突的现象
* @date: 2019/9/26 0026 下午 16:07
* @Version: V1.0
*/
public class CustomPropertiesTypeBeanInitialization {
private final static Logger logger = LoggerFactory.getLogger(CustomPropertiesTypeBeanInitialization.class);
/**
* 首先获取
*
* @return
*/
public static Map getMap() {
logger.info("init...");
Map map
= new HashMap<>(CustomerPropertiesTypeEnum.values().length);
// 首先获取 CustomerPropertiesHandler 接口的所有的实现类
Map clazzes = SpringContext.getApplicationContext().getBeansOfType(CustomerPropertiesHandler.class);
for (Map.Entry entry : clazzes.entrySet()) {
logger.info("解析到的class文件:{}", entry.getValue().getClass());
CustomerPropertiesHandler handler = SpringContext.getBean(entry.getValue().getClass());
map.put(handler.type(), handler);
}
logger.info("解析后的customPropertiesMap:{}", JSONObject.toJSONString(map));
return map;
}
```
操作类有了,这里我们可以使用单例模式来获取这个Map接口,然后在系统启动的时候来调用实例化单例
```java
/**
* Copyright © 2018 五月工作室. All rights reserved.
*
* @Project: stuff
* @ClassName: CustomePropertiesTypeSingleton
* @Package: com.amos.stuff.proxyandspring
* @author: zhuqb
* @Description: 自定义属性类型单例
* @date: 2019/9/26 0026 下午 15:19
* @Version: V1.0
*/
public class CustomePropertiesTypeSingleton {
private CustomePropertiesTypeSingleton() {
}
private static class Singleton {
private static Map map;
static {
map = CustomPropertiesTypeBeanInitialization.getMap();
}
public static Map getInstance() {
return map;
}
}
public static Map getInstance() {
return Singleton.getInstance();
}
}
/**
* Copyright © 2018 五月工作室. All rights reserved.
*
* @Project: stuff
* @ClassName: CustomPropertiesTypeRunner
* @Package: com.amos.stuff.proxyandspring.runner
* @author: zhuqb
* @Description:
* @date: 2019/9/26 0026 下午 16:38
* @Version: V1.0
*/
@Component
public class CustomPropertiesTypeRunner implements ApplicationRunner {
public final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void run(ApplicationArguments args) throws Exception {
this.logger.info("自定义属性类型初始化");
Map map = CustomePropertiesTypeSingleton.getInstance();
CustomerPropertiesHandler handler = map.get(CustomerPropertiesTypeEnum.arithmeticMultiSummation);
handler.handler(null);
}
}
```
这样我们就完成了在系统启动的时候完成了自定义属性处理器和自定义属性类型的Map接口,接下来我们来测试下是否满足我们的需求,编写测试方法
```java
/**
* Copyright © 2018 五月工作室. All rights reserved.
*
* @Project: stuff
* @ClassName: CustomPropertiesController
* @Package: com.amos.stuff.proxyandspring.web
* @author: zhuqb
* @Description: 自定义属性Controller
* @date: 2019/9/27 0027 上午 9:51
* @Version: V1.0
*/
@RestController
@RequestMapping(value = "/custom-properties")
public class CustomPropertiesController extends BaseController {
@GetMapping(value = "/handle/{handler}")
public Result customProperties(@PathVariable("handler") CustomerPropertiesTypeEnum typeEnum) {
this.logger.info(typeEnum.toString());
return ResultWapper.success(CustomePropertiesTypeSingleton.getInstance().get(typeEnum).handler(null));
}
}
```
上面代码中的参数为枚举类型,SpringBoot对接收参数为枚举类型的,需要转换下类型,这里我们进行如下设置,代码不做详细说明,博友可以参考网上相关配置说明:
```java
/**
* Copyright © 2018 五月工作室. All rights reserved.
*
* @Project: stuff
* @ClassName: EnumConverterFactory
* @Package: com.amos.stuff.common.service
* @author: zhuqb
* @Description:
* @date: 2019/9/27 0027 上午 10:35
* @Version: V1.0
*/
public class EnumConverterFactory implements ConverterFactory {
private static Map convertMap = new ConcurrentHashMap<>();
@Override
public Converter getConverter(Class aClass) {
Converter converter = convertMap.get(aClass);
if (null == converter) {
converter = new EnumConverter(aClass);
convertMap.put(aClass, converter);
}
return converter;
}
class EnumConverter implements Converter {
private Class clazz;
private Map enumMap = new ConcurrentHashMap<>();
public EnumConverter(Class clazz) {
this.clazz = clazz;
T[] enums = clazz.getEnumConstants();
for (T anEnum : enums) {
this.enumMap.put(anEnum.getKey(), anEnum);
}
}
@Override
public T convert(String key) {
T result = this.enumMap.get(key);
if (null == result) {
throw new IllegalArgumentException("params is wrong");
}
return result;
}
}
}
```
```java
/**
* Copyright © 2018 五月工作室. All rights reserved.
*
* @Project: stuff
* @ClassName: WebAppConfigurer
* @Package: handler
* @author: zhuqb
* @Description:
* @date: 2019/9/27 0027 上午 10:49
* @Version: V1.0
*/
@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(new EnumConverterFactory());
}
}
```
接下来我们使用postman来执行测试下,应该可以看到想要的结果了
### 总结
如果需要接入我们上面的代码,需要添加一种自定义属性处理器则需要如下的操作
- 在 `CustomerPropertiesTypeEnum`类中添加自定义属性类型
- 新增继承 `AbstractCustomerPropertiesHandler`的对应的自定义属性处理器,并且在`type`方法中返回自定义属性类型
完成以上两步的接入就可以使用了
详细代码,可以参考我的[Gitee](https://gitee.com/amos_zhu/stuff/tree/master/src/main/java/com/amos/stuff)