美文网首页
Spring中的设计模式

Spring中的设计模式

作者: Burlong | 来源:发表于2021-09-15 09:23 被阅读0次

    代理模式


    代理是指它与被代理对象实现了相同的接口,客户端必须通过代理才能与被代理的目标类进行交互,而代理一般在交互的过程中(交互前后),进行某些特定的处理,比如在调用这个方法前做前置处理,调用这个方法后做后置处理。

    代理又分为静态代理和动态代理两种方式,Spring的AOP采用的是动态代理的方式

    Spring通过动态代理对类进行方法级别的切面增强,动态生成目标对象的代理类,并在代理类的方法中设置拦截器,通过执行拦截器中的逻辑增强了代理方法的功能,从而实现AOP。

    策略模式


    接着上面的代理模式,看Spring的源码可以发现,Spring Aop支持JDK动态代理实现和cglib实现,AopProxy是策略接口,JdkDynamicAopProxy、CglibAopProxy是两个实现了AopProxy接口的策略类。

    策略接口定义如下:

    public interface AopProxy {
    
        /**
         * Create a new proxy object.
         * <p>Uses the AopProxy's default class loader (if necessary for proxy creation):
         * usually, the thread context class loader.
         * @return the new proxy object (never {@code null})
         * @see Thread#getContextClassLoader()
         */
        Object getProxy();
    
        /**
         * Create a new proxy object.
         * <p>Uses the given class loader (if necessary for proxy creation).
         * {@code null} will simply be passed down and thus lead to the low-level
         * proxy facility's default, which is usually different from the default chosen
         * by the AopProxy implementation's {@link #getProxy()} method.
         * @param classLoader the class loader to create the proxy with
         * (or {@code null} for the low-level proxy facility's default)
         * @return the new proxy object (never {@code null})
         */
        Object getProxy(@Nullable ClassLoader classLoader);
    }
    
    

    策略模式中,策略一般通过策略类工厂来创建,在Spring源码中,可以看到AopProxyFactory是一个工厂类接口。

    public interface AopProxyFactory {
    
        /**
         * Create an {@link AopProxy} for the given AOP configuration.
         * @param config the AOP configuration in the form of an
         * AdvisedSupport object
         * @return the corresponding AOP proxy
         * @throws AopConfigException if the configuration is invalid
         */
        AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
    
    }
    
    

    DefaultAopProxyFactory则是实现AopProxy的一个默认工厂类,用来创建AopProxy对象。如下图,策略实例在createAopProxy方法中创建。

    (hasNoUserSuppliedProdyInterfaces方法则用于判断用哪种动态代理方式)

    public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
    
        @Override
        public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
            if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
                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.");
                }
                if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                    return new JdkDynamicAopProxy(config);
                }
                return new ObjenesisCglibAopProxy(config);
            }
            else {
                return new JdkDynamicAopProxy(config);
            }
        }
    
        /**
         * Determine whether the supplied {@link AdvisedSupport} has only the
         * {@link org.springframework.aop.SpringProxy} interface specified
         * (or no proxy interfaces specified at all).
         */
        private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
            Class<?>[] ifcs = config.getProxiedInterfaces();
            return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
        }
    
    }
    
    

    单例模式


    典型的应用就是bean的创建,默认都是使用单例模式。用一个ConcurrentHashMap存储,伪代码如下:

    public class DefaultSingletonBeanRegistry {
    
        //使用了线程安全容器ConcurrentHashMap,保存各种单实例对象
        private final Map singletonObjects = new ConcurrentHashMap;
    
        protected Object getSingleton(String beanName) {
        //先到HashMap中拿Object
        Object singletonObject = singletonObjects.get(beanName);
    
        //如果没拿到通过反射创建一个对象实例,并添加到HashMap中
        if (singletonObject == null) {
          singletonObjects.put(beanName,
                               Class.forName(beanName).newInstance());
       }
    
       //返回对象实例
       return singletonObjects.get(beanName);
      }
    }
    
    

    工厂方法模式


    工厂方法模式:与简单工厂不同的是,每一个工厂都只对应一个相应的对象。

    Spring对工厂方法模式的典型实现:FactoryBean。

    public interface FactoryBean<T> {
    
        String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
    
        @Nullable
        T getObject() throws Exception;
    
        @Nullable
        Class<?> getObjectType();
    
        default boolean isSingleton() {
            return true;
        }
    
    

    我们对其进行一个简单的实现:

    @Component("myObject")
    public class MyObjectFactory implements FactoryBean {
    
        @Override
        public Object getObject () throws Exception {
            return new MyObject(1);
        }
    
        @Override
        public Class<?> getObjectType () {
            return MyObject.class;
        }
    
        @Override
        public boolean isSingleton () {
            return false;
        }
    }
    
    class MyObject {
        private int id;
    
        public MyObject (int id) {
            this.id = id;
        }
    }
    
    

    当调用getBean("myObject") 时,Spring通过反射机制发现MyObjectFactory实现了FactoryBean的接口,这时Spring容器就调用接口方法MyObjectFactory#getObject()方法返回。如果希望获取MyObjectFactory的实例,则需要在使用getBean(beanName) 方法时在beanName前显示的加上 "&" 前缀,例如getBean("&myObject")。

    观察者模式


    Spring对于观察者模式典型模式就是其时间发布与监听机制。三个角色:

    • Event事件(相当于消息)
    • Listener监听者(相当于观察者)
    • Publisher发送者(相当于被观察者)
    // Event事件
    public class DemoEvent extends ApplicationEvent {
      private String message;
    
      public DemoEvent(Object source, String message) {
        super(source);
      }
    
      public String getMessage() {
        return this.message;
      }
    }
    
    // Listener监听者
    @Component
    public class DemoListener implements ApplicationListener {
      @Override
      public void onApplicationEvent(DemoEvent demoEvent) {
        String message = demoEvent.getMessage();
        System.out.println(message);
      }
    }
    
    // Publisher发送者
    @Component
    public class DemoPublisher {
      @Autowired
      private ApplicationContext applicationContext;
    
      public void publishEvent(DemoEvent demoEvent) {
        this.applicationContext.publishEvent(demoEvent);
      }
    }
    
    

    适配器模式


    Spring 对控制器Controller的实现采用的就是适配器模式,Spring定义了统一的接口HandlerAdapter。

    HandlerAdapter的作用:因为Spring MVC中的Handler可以是多种/4种形式,但是Servlet需要的处理方法的结构却是固定的,都是以requestresponse为方法入参,那么如何让固定的Servlet处理方法调用灵活的Handler来进行处理呢?这就是HandlerAdapter要做的事情:适配。

    它的作用是:根据 Handler 来找到支持它的 HandlerAdapter,通过 HandlerAdapter 执行这个 Handler 得到 ModelAndView 对象。

    public interface HandlerAdapter {
    
        boolean supports(Object handler);
    
        @Nullable
        ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
    
        long getLastModified(HttpServletRequest request, Object handler);
    
    }
    
    

    并且对每种Controller定义了对应的适配器类。这些适配器类包括:AnnotationMethodHandlerAdapter、SimpleControllerHandlerAdapter、SimpleServletHandlerAdapter等。

    举例:SimpleControllerHandlerAdapter(处理实现Controller接口的Controller)

    public class SimpleControllerHandlerAdapter implements HandlerAdapter {
    
        @Override
        public boolean supports(Object handler) {
            return (handler instanceof Controller);
        }
    
        @Override
        @Nullable
        public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
    
            return ((Controller) handler).handleRequest(request, response);
        }
    
        @Override
        public long getLastModified(HttpServletRequest request, Object handler) {
            if (handler instanceof LastModified) {
                return ((LastModified) handler).getLastModified(request);
            }
            return -1L;
        }
    
    }
    
    

    举例:SimpleServletHandlerAdapter (处理实现Servlet接口的Controller)

    public class SimpleServletHandlerAdapter implements HandlerAdapter {
    
        @Override
        public boolean supports(Object handler) {
            return (handler instanceof Servlet);
        }
    
        @Override
        @Nullable
        public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
    
            ((Servlet) handler).service(request, response);
            return null;
        }
    
        @Override
        public long getLastModified(HttpServletRequest request, Object handler) {
            return -1;
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:Spring中的设计模式

          本文链接:https://www.haomeiwen.com/subject/jqdkgltx.html