赞
踩
典型用例: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容器中即可
缺点;每次都需要遍历全部的接口类,且无法控制执行顺序
典型用例: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类
典型用例:springmvc中的拦截器
之前的文章中有讲:
优点:可以按顺序执行处理器,扩展时只需要添加接口类即可
缺点;只能处理一个类,不同的类需要定义不同的责任链,可以考虑跟1.2结合实现动态处理。
前端传过来一个对应service的名字,然后用context.getBean()函数直接获取对应的请求处理类来处理。
优点:实现简单,扩展简便
缺点;需要告诉前端每个请求的处理类名,并且注入bean的时候需要保证bean名字的唯一。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。