Spring框架中的11种设计模式(设计模式之美)

适配器模式

例如Controller的三种实现方式:

  • @Controller注解
  • 实现Controller接口 + xml配置文件:配置DemoController与URL的对应关系
  • 实现Servlet接口 + xml配置文件:配置DemoController类与URL的对应关系

不同的Controller如何调用呢?可以通过适配器模式。

terface HandlerAdapter {
  boolean supports(Object var1);

  ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

  long getLastModified(HttpServletRequest var1, Object var2);
}

// 对应实现Controller接口的Controller
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
  public SimpleControllerHandlerAdapter() {
  }

  public boolean supports(Object handler) {
    return handler instanceof Controller;
  }

  public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    return ((Controller)handler).handleRequest(request, response);
  }

  public long getLastModified(HttpServletRequest request, Object handler) {
    return handler instanceof LastModified ? ((LastModified)handler).getLastModified(request) : -1L;
  }
}

// 对应实现Servlet接口的Controller
public class SimpleServletHandlerAdapter implements HandlerAdapter 

//AnnotationMethodHandlerAdapter对应通过注解实现的Controller,

策略模式

Spring AOP是通过动态代理来实现的。Spring支持两种动态代理实现方式,一种是JDK提供的动态代理实现方式,另一种是Cglib提供的动态代理实现方式。Spring会在运行时动态地选择不同的动态代理实现方式:策略模式包含三部分,策略的定义、创建和使用。

public interface AopProxy {
  Object getProxy();
  Object getProxy(ClassLoader var1);
}

public interface AopProxyFactory {
  AopProxy createAopProxy(AdvisedSupport var1) throws AopConfigException;
}

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
  public DefaultAopProxyFactory() {
  }

  public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
      return new JdkDynamicAopProxy(config);
    } else {
      Class<?> targetClass = config.getTargetClass();
      if (targetClass == null) {
        throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
      } else {
        return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
      }
    }
  }

  //用来判断用哪个动态代理实现方式
  private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
    Class<?>[] ifcs = config.getProxiedInterfaces();
    return ifcs.length == 0 || ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]);
  }
}

组合模式

Spring Cache提供了一套抽象的Cache接口。使用它我们能够统一不同缓存实现(Redis、Google Guava…)的不同的访问方式。Spring中针对不同缓存实现的不同缓存访问类,都依赖这个接口,比如:EhCacheCache、GuavaCache、NoOpCache、RedisCache、JCacheCache、ConcurrentMapCache、CaffeineCache。Cache接口的源码如下所示:

public interface Cache {
  String getName();
  Object getNativeCache();
  Cache.ValueWrapper get(Object var1);
  <T> T get(Object var1, Class<T> var2);
  <T> T get(Object var1, Callable<T> var2);
  void put(Object var1, Object var2);
  Cache.ValueWrapper putIfAbsent(Object var1, Object var2);
  void evict(Object var1);
  void clear();

  public static class ValueRetrievalException extends RuntimeException {
    private final Object key;

    public ValueRetrievalException(Object key, Callable<?> loader, Throwable ex) {
      super(String.format("Value for key '%s' could not be loaded using '%s'", key, loader), ex);
      this.key = key;
    }

    public Object getKey() {
      return this.key;
    }
  }

  public interface ValueWrapper {
    Object get();
  }
}

相关推荐

  1. Spring框架11设计模式设计模式

    2024-04-20 16:22:03       15 阅读
  2. Spring框架8设计模式

    2024-04-20 16:22:03       37 阅读
  3. Spring框架常用设计模式

    2024-04-20 16:22:03       43 阅读
  4. MyBatis框架5设计模式总结

    2024-04-20 16:22:03       41 阅读
  5. Spring经典9设计模式

    2024-04-20 16:22:03       26 阅读
  6. 深入探索Spring框架设计模式精髓

    2024-04-20 16:22:03       14 阅读
  7. Spring 框架用到设计模式

    2024-04-20 16:22:03       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-20 16:22:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-20 16:22:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-20 16:22:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-20 16:22:03       20 阅读

热门阅读

  1. 【LeetCode热题100】【贪心算法】划分字母区间

    2024-04-20 16:22:03       10 阅读
  2. vue admin pro 角色不同显示不同页面

    2024-04-20 16:22:03       14 阅读
  3. 【LeetCode热题100】【图论】岛屿数量

    2024-04-20 16:22:03       10 阅读
  4. 2-内核开发-第一个内核Hello模块开发案例

    2024-04-20 16:22:03       12 阅读
  5. Avi Wigderson:理论计算科学的先驱者与图灵奖得主

    2024-04-20 16:22:03       14 阅读
  6. 五个关于CSS3的常见面试题及其答案

    2024-04-20 16:22:03       12 阅读
  7. Mac 安装comfigUI (M1)

    2024-04-20 16:22:03       13 阅读
  8. CentOS 系统上使用 yum 安装 Nginx 及其模块

    2024-04-20 16:22:03       13 阅读
  9. html2pdf,qrcode库及url参数拼接

    2024-04-20 16:22:03       11 阅读