1.循环判断法
典型用例:springmvc中的handlerAdapter中
在执行类中定义判断方法和执行方法。
public interface HandlerAdapter {
//判断该实现类是否能在这个对象上使用
boolean support(Object handler);
//执行方法
Class<?> process(Object handler);
}
提前注入所有的handlerAdapter类(所有的实现类需要交给spring容器保管)
@Component
public class HandlerAdapterContext {
@Autowired
private List<HandlerAdapter> handlerAdapterList; //注册所有的HandlerAdapter类
public List<HandlerAdapter> getHandlerAdapterList(){
return handlerAdapterList;
}
}
客户端:
public class Client {
@Autowired
private HandlerAdapterContext handlerAdapterContext;
@Test
public void test(){
Object o = new Object();
for (HandlerAdapter handlerAdapter : handlerAdapterContext.getHandlerAdapterList()) {
if (handlerAdapter.support(o)) {//找到适配的就执行
o = handlerAdapter.process(o);
}
}
}
}
优点:扩展时只需要将新的接口实现类注入到sprin容器中即可
缺点;每次都需要遍历全部的接口类,且无法控制执行顺序
2.map获取法
典型用例:springmvc中参数转换,将string类型的接收参数动态的转换成函数的参数类型
定义接口类:
public interface ParseStringValue {
Object parse(String value);
}
定义实现类:
public class LongParseStringValue implements ParseStringValue{
@Override
public Object parse(String value) {
return Long.valueOf(value);
}
}
public class IntegerParseStringValue implements ParseStringValue{
@Override
public Object parse(String value) {
return Integer.valueOf(value);
}
}
public class DoubleParseStringValue implements ParseStringValue{
@Override
public Object parse(String value) {
return Double.valueOf(value);
}
}
提前注入实现类。如果在spring中的话可以使用@PostConstruct
public class ParseStringValueContext {
private static Map<Class<?>, ParseStringValue> parseStringValueMap;
static {
parseStringValueMap = new HashMap<>();
parseStringValueMap.put(Integer.class, new IntegerParseStringValue());
parseStringValueMap.put(Double.class, new DoubleParseStringValue());
parseStringValueMap.put(Long.class, new LongParseStringValue());
}
public static ParseStringValue getResolver(Class<?> clazz){
return parseStringValueMap.get(clazz);
}
}
使用:
public class Client {
private static void test(Integer num1, Long num2, Double num3) {
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
System.out.println("num3 = " + num3);
}
public static void main(String[] args) {
String[] requestParameters = new String[]{"111", "1111111111111111", "1.11"};//模拟请求参数
try {
Method method = Client.class.getDeclaredMethod("test", Integer.class, Long.class, Double.class);
List<Object> values = new ArrayList<>();
Parameter[] parameters = method.getParameters();
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
//根据参数类型解析参数
ParseStringValue resolver = ParseStringValueContext.getResolver(parameter.getType());
Object parse = resolver.parse(requestParameters[i]);
values.add(parse);
}
Client client = Client.class.getDeclaredConstructor().newInstance((Object[]) args);
method.invoke(client, values.get(0), values.get(1), values.get(2));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
结果:
优点:可以自定义处理器的获取方式,比如用class来获取
缺点;无法控制执行顺序,扩展时需要额外修改context类
3.责任链模式
典型用例:springmvc中的拦截器
之前的文章中有讲:
优点:可以按顺序执行处理器,扩展时只需要添加接口类即可
缺点;只能处理一个类,不同的类需要定义不同的责任链,可以考虑跟1.2结合实现动态处理。
4.利用spring上下文
前端传过来一个对应service的名字,然后用context.getBean()函数直接获取对应的请求处理类来处理。
优点:实现简单,扩展简便
缺点;需要告诉前端每个请求的处理类名,并且注入bean的时候需要保证bean名字的唯一。