精华内容
下载资源
问答
  • 1.模板模式 Spring IOC容器的初始化过程->AbstractApplicationContext.java抽象类 -> refresh()方法,就是一个模板方法

    1.模板模式

    1.JDK->AQS,基于AQS创建锁

    AbstractQueuedSynchronizer:抽象类,AQS框架核心类,其内部以虚拟队列的方式管理线程的锁获取与锁释放,其中获取锁(tryAcquire方法)和释放锁(tryRelease方法)并没有提供默认实现,需要子类重写这两个方法实现具体逻辑,目的是使开发人员可以自由定义获取锁以及释放锁的方式。

    这个抽象类提供了两个钩子方法tryAcquire(int arg)与tryRelease(int arg), 需要子类去实现。 从设计模式角度来看,AQS采用的模板模式的方式构建的,其内部除了提供并发操作核心方法以及同步队列操作外,还提供了一些模板方法让子类自己实现,如加锁操作以及解锁操作,为什么这么做?这是因为AQS作为基础组件,封装的是核心并发操作,但是实现上分为两种模式,即共享模式独占模式,而这两种模式的加锁与解锁实现方式是不一样的,但AQS只关注内部公共方法实现并不关心外部不同模式的实现,所以提供了模板方法给子类使用,也就是说实现独占锁,如ReentrantLock需要自己实现tryAcquire()方法和tryRelease()方法,而实现共享模式的Semaphore,则需要实现tryAcquireShared()方法和tryReleaseShared()方法,这样做的好处是显而易见的,无论是共享模式还是独占模式,其基础的实现都是同一套组件(AQS),只不过是加锁解锁的逻辑不同罢了,更重要的是如果我们需要自定义锁的话,也变得非常简单,只需要选择不同的模式实现不同的加锁和解锁的模板方法即可

    2.Spring IOC容器的初始化

    Spring IOC容器的初始化过程->AbstractApplicationContext.java抽象类 -> refresh()方法,就是一个模板方法。

    AbstractApplicationContext.java抽象类 -> refresh()方法 -> postProcessBeanFactory(beanFactory),是一个钩子方法,一个空方法,没有实现任何功能,由子类根据情况去实现。

    AbstractApplicationContext.java抽象类 -> refresh()方法 -> onRefresh(),也是一个钩子方法,一个空方法,没有实现任何功能,由子类根据情况去实现。

    子类的实现:

    ConfigurableApplicationContext.java(接口) -> AbstractApplicationContext(实现了ConfigurableApplicationContext.java) -> GenericApplicationContext.java(继承了AbstractApplicationContext)

    1. 抽象模板类 -> 模板方法 -> 模板方法调用普通方法,抽象方法,钩子方法。
    2. 子类继承抽象模板类 -> 实现抽象方法,钩子方法

    我们常用的创建IOC容器的AnnotationConfigWebApplicationContextClassPathXmlApplicationContext类,最终都是继承于AbstractApplicationContext.java抽象类

    3.Spring 依赖注入:

    Spring依赖注入有两种方式,单例和prototype,分别用到了单例模式和原型模式。

    4.Spring AOP:

    AOP具体是由动态代理实现的,代理模式。

    5.SpringMVC:

    职责链模式和适配器模式

    6.SpringSecurity:

    深入理解Spring Security之过滤器责任链模式分析_李永志的博客-CSDN博客

    职责链模式:

    Spring Security 中的过滤器链就是一种责任链模式。一个请求到达后,被过滤器链中的过滤器逐个进行处理,过滤器链中的过滤器每个都具有不同的职能并且互不相扰,我们还可以通过 HttpSecurity 来动态配置过滤器链中的过滤器(即添加/删除过滤器链中的过滤器)。

      @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    ....
                    //在这里添加了过滤器,这里指定了配置过滤器并且配置的位置
                   .addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class)
        }

    展开全文
  • Spring中用到了哪些设计模式

    千次阅读 2020-07-16 01:20:55
    Spring 中用到了那些设计模式?这两个问题,在面试中比较常见。我在网上搜索了一下关于 Spring设计模式的讲解几乎都是千篇一律,而且大部分都年代久远。所以,花了几天时间自己总结了一下,由于我的个人能力有限,...

    谈谈Spring中都用到了哪些设计模式?

    JDK 中用到了那些设计模式?Spring 中用到了那些设计模式?这两个问题,在面试中比较常见。我在网上搜索了一下关于 Spring 中设计模式的讲解几乎都是千篇一律,而且大部分都年代久远。所以,花了几天时间自己总结了一下,由于我的个人能力有限,文中如有任何错误各位都可以指出。另外,文章篇幅有限,对于设计模式以及一些源码的解读我只是一笔带过,这篇文章的主要目的是回顾一下 Spring 中的常见的设计模式。

    Design Patterns(设计模式) 表示面向对象软件开发中最好的计算机编程实践。 Spring 框架中广泛使用了不同类型的设计模式,下面我们来看看到底有哪些设计模式?

    控制反转(IOC)和依赖注入(DI)

    IoC(Inversion of Control,控制翻转) 是Spring 中一个非常非常重要的概念,它不是什么技术,而是一种解耦的设计思想。它的主要目的是借助于“第三方”(即Spring 中的 IOC 容器) 实现具有依赖关系的对象之间的解耦(IOC容易管理对象,你只管使用即可),从而降低代码之间的耦合度。IOC 是一个原则,而不是一个模式,以下模式(但不限于)实现了IoC原则。

    ​ ioc-patterns

    Spring IOC容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。IOC 容器负责创建对象,将对象连接在一起,配置这些对象,并从创建中处理这些对象的整个生命周期,直到它们被完全销毁。

    在实际项目中一个 Service 类如果有几百甚至上千个类作为它的底层,我们需要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IOC 的话,你只需要配置好,然后在需要的地方引用就行了,这大大增加了项目的可维护性且降低了开发难度。关于Spring IOC 的理解,推荐看这一下知乎的一个回答:

    ,非常不错。

    控制翻转怎么理解呢? 举个例子:"对象a 依赖了对象 b,当对象 a 需要使用 对象 b的时候必须自己去创建。但是当系统引入了 IOC 容器后, 对象a 和对象 b 之前就失去了直接的联系。这个时候,当对象 a 需要使用 对象 b的时候, 我们可以指定 IOC 容器去创建一个对象b注入到对象 a 中"。 对象 a 获得依赖对象 b 的过程,由主动行为变为了被动行为,控制权反转了,这就是控制反转名字的由来。

    DI(Dependency Inject,依赖注入),是实现控制反转的一种设计模式,依赖注入就是将实例变量传入到一个对象中去。

    工厂设计模式

    Spring使用工厂模式可以通过 BeanFactory 或 ApplicationContext 创建 bean 对象。

    两者对比:

    • BeanFactory :延迟注入(使用到某个 bean 的时候才会注入),相比于BeanFactory来说会占用更少的内存,程序启动速度更快。
    • ApplicationContext :容器启动的时候,不管你用没用到,一次性创建所有 bean 。BeanFactory 仅提供了最基本的依赖注入支持,ApplicationContext 扩展了 BeanFactory ,除了有BeanFactory的功能之外还有额外更多功能,所以一般开发人员使用ApplicationContext会更多。

    ApplicationContext的三个实现类:

    1. ClassPathXmlApplication:把上下文文件当成类路径资源。
    2. FileSystemXmlApplication:从文件系统中的 XML 文件载入上下文定义信息。
    3. XmlWebApplicationContext:从Web系统中的XML文件载入上下文定义信息。

    Example:

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.FileSystemXmlApplicationContext;
    
    public class App {
        public static void main(String[] args) {
            ApplicationContext context = new FileSystemXmlApplicationContext(
                    "C:/work/IOC Containers/springframework.applicationcontext/src/main/resources/bean-factory-config.xml");
    
            HelloApplicationContext obj = (HelloApplicationContext) context.getBean("helloApplicationContext");
            obj.getMsg();
        }
    }
    

    单例设计模式

    在我们的系统中,有一些对象其实我们只需要一个,比如说:线程池、缓存、对话框、注册表、日志对象、充当打印机、显卡等设备驱动程序的对象。事实上,这一类对象只能有一个实例,如果制造出多个实例就可能会导致一些问题的产生,比如:程序的行为异常、资源使用过量、或者不一致性的结果。

    使用单例模式的好处:

    • 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;
    • 由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。

    Spring中bean的默认作用域就是singleton(单例)的,除了singleton作用域,Spring中bean还有下面几种作用域:

    • prototype : 每次请求都会创建一个新的 bean 实例。
    • request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
    • session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。
    • global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话

    Spring实现单例的方式:

    • xml:<bean id="userService" class="top.snailclimb.UserService" scope="singleton"/>
    • 注解:@Scope(value = "singleton")

    Spring通过ConcurrentHashMap实现单例注册表的特殊方式实现单例模式。Spring实现单例的核心代码如下:

    // 通过 ConcurrentHashMap(线程安全) 实现单例注册表
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
    
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(beanName, "'beanName' must not be null");
            synchronized (this.singletonObjects) {
                // 检查缓存中是否存在实例  
                Object singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    //...省略了很多代码
                    try {
                        singletonObject = singletonFactory.getObject();
                    }
                    //...省略了很多代码
                    // 如果实例对象在不存在,我们注册到单例注册表中。
                    addSingleton(beanName, singletonObject);
                }
                return (singletonObject != NULL_OBJECT ? singletonObject : null);
            }
        }
        //将对象添加到单例注册表
        protected void addSingleton(String beanName, Object singletonObject) {
                synchronized (this.singletonObjects) {
                    this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
    
                }
            }
    }
    

    代理设计模式

    AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

    Spring AOP就是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,Spring AOP会使用Cglib,这时候Spring AOP会使用Cglib生成一个被代理对象的子类来作为代理,如下图所示:

    当然你也可以使用AspectJ,Spring AOP以及集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。

    使用AOP之后我们可以把一些通用的功能抽象出来,在在需要用到的地方直接使用即可,这样大大简化了代码量。我们需要增加新功能时也方便,这样也提高了系统扩展性。日志功能、事务管理等等场景都用到了 AOP 。

    Spring AOP 和 AspectJ AOP 有什么区别?

    Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)

    Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单,功能更弱。

    如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比Spring AOP 快很多。

    模板方法

    模板方法模式是一种行为设计模式,它定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤的实现方式。

    public abstract class Template {
        //这是我们的模板方法
        public final void TemplateMethod(){
            PrimitiveOperation1();  
            PrimitiveOperation2();
            PrimitiveOperation3();
        }
    
        protected void  PrimitiveOperation1(){
            //当前类实现
        }
    
        //被子类实现的方法
        protected abstract void PrimitiveOperation2();
        protected abstract void PrimitiveOperation3();
    
    }
    public class TemplateImpl extends Template {
    
        @Override
        public void PrimitiveOperation2() {
            //当前类实现
        }
    
        @Override
        public void PrimitiveOperation3() {
            //当前类实现
        }
    }
    

    Spring 中 jdbcTemplatehibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。一般情况下,我们都是使用继承的方式来实现模板模式,但是 Spring 并没有使用这种方式,而是使用Callback 模式与模板方法模式配合,既达到了代码复用的效果,同时增加了灵活性。

    观察者模式

    观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。

    观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。

    Spring 事件驱动模型中的三种角色

    事件角色

    ApplicationEvent (org.springframework.context包下)充当事件的角色,这是一个抽象类,它继承了java.util.EventObject并实现了 java.io.Serializable接口。

    Spring 中默认存在以下事件,他们都是对 ApplicationContextEvent 的实现(继承自ApplicationContextEvent):

    • ContextStartedEventApplicationContext 启动后触发的事件;
    • ContextStoppedEventApplicationContext 停止后触发的事件;
    • ContextRefreshedEventApplicationContext 初始化或刷新完成后触发的事件;
    • ContextClosedEventApplicationContext 关闭后触发的事件。

    事件监听者角色

    ApplicationListener 充当了事件监听者角色,它是一个接口,里面只定义了一个 onApplicationEvent()方法来处理ApplicationEventApplicationListener接口类源码如下,可以看出接口定义看出接口中的事件只要实现了 ApplicationEvent就可以了。所以,在 Spring中我们只要实现 ApplicationListener 接口实现 onApplicationEvent() 方法即可完成监听事件

    package org.springframework.context;
    import java.util.EventListener;
    @FunctionalInterface
    public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
        void onApplicationEvent(E var1);
    }
    

    事件发布者角色

    ApplicationEventPublisher 充当了事件的发布者,它也是一个接口。

    @FunctionalInterface
    public interface ApplicationEventPublisher {
        default void publishEvent(ApplicationEvent event) {
            this.publishEvent((Object)event);
        }
    
        void publishEvent(Object var1);
    }
    

    ApplicationEventPublisher 接口的publishEvent()这个方法在AbstractApplicationContext类中被实现,阅读这个方法的实现,你会发现实际上事件真正是通过ApplicationEventMulticaster来广播出去的。具体内容过多,就不在这里分析了,后面可能会单独写一篇文章提到。

    Spring 的事件流程总结

    1. 定义一个事件: 实现一个继承自 ApplicationEvent,并且写相应的构造函数;
    2. 定义一个事件监听者:实现 ApplicationListener 接口,重写 onApplicationEvent() 方法;
    3. 使用事件发布者发布消息: 可以通过 ApplicationEventPublisher 的 publishEvent() 方法发布消息。

    Example:

    // 定义一个事件,继承自ApplicationEvent并且写相应的构造函数
    public class DemoEvent extends ApplicationEvent{
        private static final long serialVersionUID = 1L;
    
        private String message;
    
        public DemoEvent(Object source,String message){
            super(source);
            this.message = message;
        }
    
        public String getMessage() {
             return message;
              }
    
    
    // 定义一个事件监听者,实现ApplicationListener接口,重写 onApplicationEvent() 方法;
    @Component
    public class DemoListener implements ApplicationListener<DemoEvent>{
    
        //使用onApplicationEvent接收消息
        @Override
        public void onApplicationEvent(DemoEvent event) {
            String msg = event.getMessage();
            System.out.println("接收到的信息是:"+msg);
        }
    
    }
    // 发布事件,可以通过ApplicationEventPublisher  的 publishEvent() 方法发布消息。
    @Component
    public class DemoPublisher {
    
        @Autowired
        ApplicationContext applicationContext;
    
        public void publish(String message){
            //发布事件
            applicationContext.publishEvent(new DemoEvent(this, message));
        }
    }
    

    当调用 DemoPublisher 的 publish() 方法的时候,比如 demoPublisher.publish("你好") ,控制台就会打印出:接收到的信息是:你好

    适配器模式

    适配器模式(Adapter Pattern) 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。

    spring AOP中的适配器模式

    我们知道 Spring AOP 的实现是基于代理模式,但是 Spring AOP 的增强或通知(Advice)使用到了适配器模式,与之相关的接口是AdvisorAdapter 。Advice 常用的类型有:BeforeAdvice(目标方法调用前,前置通知)、AfterAdvice(目标方法调用后,后置通知)、AfterReturningAdvice(目标方法执行结束后,return之前)等等。每个类型Advice(通知)都有对应的拦截器:MethodBeforeAdviceInterceptorAfterReturningAdviceAdapterAfterReturningAdviceInterceptor。Spring预定义的通知要通过对应的适配器,适配成 MethodInterceptor接口(方法拦截器)类型的对象(如:MethodBeforeAdviceInterceptor 负责适配 MethodBeforeAdvice)。

    spring MVC中的适配器模式

    在Spring MVC中,DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由HandlerAdapter 适配器处理。HandlerAdapter 作为期望接口,具体的适配器实现类用于对目标类进行适配,Controller 作为需要适配的类。

    为什么要在 Spring MVC 中使用适配器模式? Spring MVC 中的 Controller 种类众多,不同类型的 Controller 通过不同的方法来对请求进行处理。如果不利用适配器模式的话,DispatcherServlet 直接获取对应类型的 Controller,需要的自行来判断,像下面这段代码一样:

    if(mappedHandler.getHandler() instanceof MultiActionController){  
       ((MultiActionController)mappedHandler.getHandler()).xxx  
    }else if(mappedHandler.getHandler() instanceof XXX){  
        ...  
    }else if(...){  
       ...  
    }  
    

    假如我们再增加一个 Controller类型就要在上面代码中再加入一行 判断语句,这种形式就使得程序难以维护,也违反了设计模式中的开闭原则 – 对扩展开放,对修改关闭。

    装饰者模式

    装饰者模式可以动态地给对象添加一些额外的属性或行为。相比于使用继承,装饰者模式更加灵活。简单点儿说就是当我们需要修改原有的功能,但我们又不愿直接去修改原有的代码时,设计一个Decorator套在原有代码外面。其实在 JDK 中就有很多地方用到了装饰者模式,比如 InputStream家族,InputStream 类下有 FileInputStream (读取文件)、BufferedInputStream (增加缓存,使读取文件速度大大提升)等子类都在不修改InputStream 代码的情况下扩展了它的功能。


    ​ 装饰者模式示意图

    Spring 中配置 DataSource 的时候,DataSource 可能是不同的数据库和数据源。我们能否根据客户的需求在少修改原有类的代码下动态切换不同的数据源?这个时候就要用到装饰者模式(这一点我自己还没太理解具体原理)。Spring 中用到的包装器模式在类名上含有 Wrapper或者 Decorator。这些类基本上都是动态地给一个对象添加一些额外的职责

    总结

    Spring 框架中用到了哪些设计模式:

    • 工厂设计模式 : Spring使用工厂模式通过 BeanFactoryApplicationContext 创建 bean 对象。
    • 代理设计模式 : Spring AOP 功能的实现。
    • 单例设计模式 : Spring 中的 Bean 默认都是单例的。
    • 模板方法模式 : Spring 中 jdbcTemplatehibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
    • 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
    • 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
    • 适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller
    展开全文
  • Spring源码中用到设计模式一、策略模式二、观察者模式三、装饰器模式 一、策略模式 首先讲两个面向对象设计原则: 找出应用中可能需要变化的部分,把他们独立出来,不要和那些不需要变化的代码混在一起。 针对...

    文中代码多是用于解释的伪代码,类图排版因为工具原因没有细细打磨,凑合用了。


    耗时两周研究了这些设计模式,个人总结一下学习设计模式应该注意这些东西:

    • 相关的OO(面向对象) 设计原则

    • 首先搞清楚该模式的应用场景这非常重要

    • 搞清楚类似设计模式的核心差异,个人认为这个最重要,当你能轻松且惬意的区分那些设计模式的异同的时候,就代表你开始掌握它们了,最起码在面试中只要不是问得太刁钻应该都难不倒你了。


    1.策略模式

    关注对象变化的部分,并抽取为接口,通过引用的方式拓展对象

    面向对象设计原则:

    • 针对接口编程而不是针对实现编程
    • 多用组合少用继承

    应当找出应用中可能需要变化的部分,把他们独立出来,不要和那些不需要变化的代码混在一起。

    让我们描述一个例子,假如我们要设计一系列的哺乳动物类,他们都能跑run()、会say()、外观display();我们可以设计一个抽象类,Animal。

    1. 当需要一个Tiger老虎类时,继承Animal,并实现自己的say()(嗷嗷叫);display()(纹身的);
    2. 同理当需要狮子时,也需要继承Animal,实现say() (嗷嗷叫);display() (烫头的);
    3. 。。。。。每一个新的动物都需要去继承基类,并完成自己say、display。。。

    利用 继承\接口 实现动物类

    public class Dog extends Animal{
        public Dog(String name){
            super(name);
        }    
        @Override
        public void say(){
            System.out.println("我会汪汪叫 ");
        }
        @Override
        public  void display(){
            System.out.println("我有纯黑色的外观");
        }
    }
    
    public class Cat extends Animal{
        public Cat(String name){
            super(name);
        }
        
        @Override
        public void say(){
            System.out.println("我会喵喵叫 ");
        }
        @Override
        public  void display(){
            System.out.println("我有纯黑色的外观");
        }
    }
    
    

    这样做会导致大量的重复编码,例如:狮子和老虎都会嗷嗷叫,但是外形不同;斑马和老虎都是条纹外观,但是斑马不会嗷嗷叫,,,逐一实现这些类,就代表无尽的重复编码,,,

    这个时候,结合上述描述,引入策略模式,我们可以把定义两个接口:

    • sayInterface,它的实现类SayInterfaceImpl可以为:嗷嗷叫、喵喵叫、咩咩叫、哞哞叫、汪汪叫等动作
    • displayInterface,它的实现类DisplayInterfaceImpl可以为:纹身、烫头、纯黑外观、棕色外观等等

    这样,Animal就只留下了通用(不变)的部分:run,因为所有哺乳动物都会跑

    策略模式一览:

    public class Animal{
    	private SayInterface sayInterface;
    	private DisplayInterface displayInterface;
    	private String name;
    	public Animal(SayInterface dayInterface,DisplayInterface displayInterface,String name){
    		xxxxx xxxx = xxx;
    		xxxx   xxx = xxx;
    		.......
    	}
    	public void say(){
    		sayInterface.say();
    	}
    	public void display(){
    		displayInterface.display();
    	}
    	public static void main(String[] args){
    		Animal tiger = new Animal(new SayInterfaceImpl(),new DisplayInterfaceImpl(),"Tiger");
    	}
    }
    

    结合java向下转型的特性,相信你已经明白了策略模式要做什么了吧,我们把变化的部分,say、display抽取出来,成为了接口,我们可以预先定义好所有的叫声、外观,当我们要创建一种动物时,可以进行动态的设置外观、叫声,这样的实现,减少代码重复、降低耦合从而减少出现牵一发而动全身的状况、代码的可拓展性增强。

    试想一下,按照最初的方式去实现动物类,会有多么麻烦?

    观察者模式,通过组合获得了变化的能力;通过抽取变化的部分,并通过接口去定义,省去了大量的重复工作。

    最后说下策略模式的定义:

    策略模式:
    它定义一个或多个算法族,分别封装起来,属于同一算法族的算法之间可以相互替换,此模式让算法的变化独立于使用算法的客户

    PS * 算法 – (动作、特性)

    2.观察者模式

    对象一对多的依赖、广播

    面向对象设计原则

    • 为交互对象之间的松耦合设计而努力

    所谓观察者模式,先讲一下它的概念:

    它定义了对象间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

    在这里插入图片描述

    Observable 被观察者抽象类,它依赖于一个观察者集合
    Observer 观察者接口
    定义上述接口和抽象类可以实现解耦,具体的被观察者和观察者通过 继承/实现接口 实现。
    被观察者只有一众观察者对象的引用,每当被观察者,发生变化,即可通过持有的一对多的引用,去通知所有观察者。

    我们可以看到,被观察者,依赖的时观察者实现的接口,而非具体的观察者类,这就是松耦合的体现。

    PS *

    1. 三角实线:继承
    2. 三角虚线:实现接口
    3. 箭头实现:引用

    3.装饰者模式

    不修改现有代码的情况下对类进行拓展,添加新的行为
    面向对象设计原则:

    • 对拓展开放,对修改关闭

    装饰者模式定义:

    动态的将责任附加到对象上,装饰者模式提供了有别于继承的功能拓展方式。

    在这里插入图片描述

    • ConcreteComponent 组件
    • Decorator 装饰者抽象类,每个装饰者持有一个组件基类引用(向下转型,松耦合)。

    装饰者模式案例: Jva I/O

    可以使用无数个装饰者包装一个组件,装饰的基类,与组件类实现同样的抽象基类,装饰者是在不修改组件代码的情况下对组件功能的拓展。

    4.工厂模式

    关注对象的创建,并使具体对象的创建与应用程序解耦

    面向对象设计原则

    • 依赖抽象,不要依赖具体实现。

    对比策略模式学习中提到的:针对接口编程,而不是实现编程;他们强调的东西不同。

    依赖抽象,的原则更强调抽象,不能让高层组件依赖底层组件,他们都应该依赖抽象<依赖倒置>。
    PS * 高层组件:由其他底层组件定义其行为。(例如类A,它的所有行为由它的变量B对象实现,那么最好B是一个抽象组件,A依赖B, 且实现或继承了 B类 的 “子类bx” 类依赖B)。

    工厂方法模式

    模式定义:

    • 它定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
      在这里插入图片描述

    Product 工厂的产品的基类
    Creater 实现了除工厂方法外的所有操作产品的方法,工厂方法factoryMethod定义为抽象方法,由其子类实现具体的工厂方法,决定产出Product的某个或某些具体实现。

    Creator 依赖 Product , 而具体的产品实现也依赖 Product,即实现了依赖倒置。
    如果不使用工厂方法模式,那么所有的具体产品都依赖于Creator;

    解耦高层组件对具体的低层组件的依赖,他们都应该依赖于底层组件的抽象。

    设计指导方针:

    1. 变量不可以持有具体类型;
    2. 不要让类派生自具体类(应该是抽象类)。
    3. 不要覆盖基类中实现了的方法。

    抽象工厂模式

    • 抽象工厂模式提供一个接口,用于创建相关或依赖的对象家族,而不需要明确指定具体类。

    先看一个完整类图:
    在这里插入图片描述
    由于工具原因,略微混乱,如下面两张图,我把他们拆开了。

    • Client 客户代码,它依赖抽象产品:AbstractProductA 和 AbstractProductB

    • AbstractFactory 他是一个抽象工厂,它的实现类–ConcreteFactory 会产生,上述抽象产品的具体实现产品族。

    • Client 依赖抽象工厂,至于工厂具体产出什么产品并不关心。

    • ConcreteFactory 实现自己的方法,产出抽线产品的实现

    • ConcreteFactory1 通过creatA()和creatB() 方法产生,ProductA1和ProductB1

    • ConcreteFactory2 通过creatA()和creatB() 方法产生,ProductA2和ProductB2

    在这里插入图片描述

    在这里插入图片描述

    工厂方法和抽象工厂的异同

    • 他们都被广泛应用于将应用程序从特定实现中解耦

    • 工厂方法模式的实现方式是通过继承一个抽象类实现,并实现抽象类中定义的抽象方法,获得具体产品;可以认为工厂方法模式就是通过子类创建产品对象,(父类依赖抽象产品)。

    • 而抽象工厂模式则是通过对象组合,把一群相关产品集合起来。

    • 抽象工厂的任务是定义一个负责创建一组产品的接口,接口里的每一个方法负责创建一个具体的产品,实现该抽象工厂接口的子类负责提供具体做法,所以抽象工厂中利用工厂方法实现生产(产品) 方法是很自然的做法。

    • 他们都旨在将对象的创建封装起来,是应用程序解耦,并降低对特定实现的依赖。(减少应用程序与具体类之间的依赖,并促进松耦合)

    抽象工厂:管理产品对象家族,它让应用程序与,产品家族的具体实现解耦(依赖抽象,而非依赖具体实现的原则。)

    工厂方法模式:把客户代码从需要实例化的具体类中解耦(依赖产品的具体实现,变更为依赖产品的抽象); 允许将类的实例化推迟到子类中进行;

    5.单例模式

    面向对象设计原则:

    • 单件模式:确保类只有一个实例,并提供一个全局访问点。

    某些场景下,需要保证类只能被实例化一次,当存在多个实例时他们可能会相互之间造成干扰,造成程序行为异常、资源使用过量等问题;例如:线程池、缓存、处理偏好设置和注册表的对象。

    总所周知,对象的创建必须使用 new 关键字调用构造方法进行,为了不让别人调用,那么需要把构造器声明为 private 私有的,同时还需要提供一个该对象的全局访问点。

    在这里插入图片描述
    极简的类图

    • 一个静态变量用于存放具体实例;
    • 一个静态方法提供全局访问点(必要时可以添加同步机制保证线程安全);
    public class Singleton{
    	// volitile 关键自保证了该单例对象的修改对所有线程可见。
    	private volatile static Singleton singletonInstance;
    	private Singleton(){
    		
    	}
    	public static Singleton getInstance(){
    		if (singletonInstance == null) {// 第一次访问尚未初始化该单例对象
    			synchronized (Singleton.class){
    				if (singletonInstance == null){ // synchronized 关键字保证只有一个对象被创建
    					singletonInstance = new Singelton();
    				}
    			}
    		}
    		return singletonInstance;
    	}
    
    }
    

    6.适配器模式与外观模式

    适配器模式


    接口转换、与实现解耦
    • 适配器模式 : 将一个类的接口转换成客户期望的零一个接口,适配器让原本不兼容的类可以合作无间。

    在这里插入图片描述

    • Client 客户代码/应用程序 依赖抽象类/接口 Target

    • 实际提供的对象为Adaptee类对象

    • 那么需要 Target 的实现,并调用Adaptee; 最终,经Adapter 转发从Client, 到 Adaptee 的请求。

    适配器模式,让不兼容的接口变成兼容,可以让客户代码从接口的实现解耦。把客户代码和接口(Target) 绑定,而不是和实现(Adapter)绑定

    外观模式


    简化并统一一个很大的接口或一群复杂接口

    面向对象设计原则:最少知识原则;

    • 外观模式:提供统一的接口,用来访问子系统中的一群接口,外观模式定义了一个高层接口,统合子系统的一系列接口,让子系统更容易使用。

    • 外观模式,可以简单视作,对一系列接口的复杂操作进行了统合,提供了一个标准化的接口操作集合。

    • 当然,当需要了解细节时也可以调用子系统的具体接口。

    • 外观模式可以降低客户代码与子系统之间的耦合,让子系统更易于使用,减少维护成本。

    • 从客户的视角看:将子系统组合进外观中,将工作委托给子系统:

        客户  ->  外观   ->  子系统
      

    7.模板方法模式

    概念

    • 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下重新定义算法中的一些步骤。

    类图:

    在这里插入图片描述
    AbstractClass 抽象类,定义了算法细节,拥有哪些步骤

    ConcreteClass  实现内,实现抽象类之中的抽象方法,必要的时候可以覆盖父类中定义的钩子方法
    
    • 钩子方法:钩子的存在可以让子类有能力对算法的不同点进行挂钩,是否挂钩由子类决定,它让子类对算法具有一定的调控能力。(例如,当算法的某些环节是可选的,那么就可以通过钩子决定)。

    面向对象设计原则:

    • 好莱坞原则: 别调用我们,我们会调用你。

    这个原则是为了避免出现依赖 “腐败”,例如高层组件依赖低层组件、低层组件又依赖高层组件、而高层组件又依赖边侧组件、边侧组件又依赖低层组件…

    好莱坞原则下,允许将底层组件将自己挂钩到系统上,但是由高层组件决定什么时候调用低层组件,也就是说:高层组件对于低层组件掌握调用主动权,不能由低层组件去调用从高层组件继承得来的方法。

    模板方法模式与策略模式异同

    • 模板方法模式:专注于一个算法,且将其细分,部分环节推迟到子类实现。使用继承,具体实现继承自抽象的超类,只需要实现部分环节,必要时可以覆盖超类的钩子方法;缺点是必须依赖超类中实现的方法。

    • 策略模式:完整实现单个算法,不进行步骤上的细分。使用组合,客户可以选择算法的实现方式(定义了一个算法家族,并且这些算法可以互换);实现完整算法,带来了代码重复的缺点。

    8.代理模式

    概念:

    • 代理模式为另一个对象提供一个替身或者占位符,以控制对这个对象的访问。也可使是视作代理对象让客户代码于实际对象解耦。使用代理模式创建代表对象,让代表对象控制对某对象的访问,被代理的对象可以是远程的对象(运行在不同JVM上,通过RMI实现)、创建开销大的对象(虚拟代理模式)或者需要安全控制的对象(保护代理模式)。

    类图:

    在这里插入图片描述

    • Subject 是需要被代理的对象的超类,实际的对象和代理对象都需要实现它

    • RealSubject 需要被控制的实际对象

    • Proxy 代理对象,它控制实际对象的访问,它持有实际对象的引用。

    • 客户通过代理取得实际对象的访问,客户对代理细节透明。

    代理模式与适配器模式的异同

    代理和适配器器都挡在其它对象前,将访问拦截;而适配器主要是为了对接口进行转化,代理模式侧重是对该对象的访问控制,需要实现相同的接口。(某些特殊的代理模式规定,只能调用部分实际对象的方法,此种情况下与适配器模式类似:“保护代理模式”)。

    代理模式与装饰者模式异同

    代理模式的功能,看起来跟很像装饰者(为对象提供新的行为)。但是,代理的目的是为了对象访问的控制;装饰者的核心目标是不改动原有对象的情况下为其增加新的行为(功能);装饰者对象的数量不限,而很少见到多层的代理;

    • 装饰者模式是为了装饰对象,并不改变对象,只是装饰不会实例化任何东西。

    • 代理模式还会控制实际对象的创建,并担任实际对象的替身。

    展开全文
  • 简单工厂模式 又叫做静态工厂方法StaticFactory Method模式但不属于 23 种 GOF 设计模式之一 简单工厂模式的实质是由一个工厂类根据传入的参数动态决定应该创建哪一个 产品类 spring 中的 BeanFactory 就是简单工厂...
  • 今天,螃蟹在IT学习者网站就设计模式的内在价值做一番探讨,并以spring为例进行讲解,只有领略了其设计的思想理念,才能在工作学习中运用“无形”。 Spring作为业界的经典框架,无论是在...

    转载:https://www.cnblogs.com/yuefan/p/3763898.html

    设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也不是我们时常忘记,只是一直没有记忆。


    今天,螃蟹在IT学习者网站就设计模式的内在价值做一番探讨,并以spring为例进行讲解,只有领略了其设计的思想理念,才能在工作学习中运用到“无形”。


    Spring作为业界的经典框架,无论是在架构设计方面,还是在代码编写方面,都堪称行内典范。好了,话不多说,开始今天的内容。


    spring中常用的设计模式达到九种,我们举例说明:


    第一种:简单工厂

    又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。 
    简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。 
    spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。如下配置,就是在 HelloItxxz 类中创建一个 itxxzBean。

    <beans>

        <bean id="singletonBean" class="com.itxxz.HelloItxxz">

            <constructor-arg>

                <value>Hello! 这是singletonBean!value>

            </constructor-arg>

       </ bean>

     

        <bean id="itxxzBean" class="com.itxxz.HelloItxxz"

            singleton="false">

            <constructor-arg>

                <value>Hello! 这是itxxzBean! value>

            </constructor-arg>

        </bean>

     

    </beans>


    第二种:工厂方法(Factory Method
     

    通常由应用程序直接使用new创建新的对象,为了将对象的创建和使用相分离,采用工厂模式,即应用程序将对象的创建及初始化职责交给工厂对象。

    一般情况下,应用程序有自己的工厂对象来创建bean.如果将应用程序自己的工厂对象交给Spring管理,那么Spring管理的就不是普通的bean,而是工厂Bean。

    螃蟹就以工厂方法中的静态方法为例讲解一下:

    import java.util.Random;

    public class StaticFactoryBean {

          public static Integer createRandom() {

               return new Integer(new Random().nextInt());

           }

    }

    建一个config.xm配置文件,将其纳入Spring容器来管理,需要通过factory-method指定静态方法名称

    <bean id="random"

    class="example.chapter3.StaticFactoryBean" factory-method="createRandom" //createRandom方法必须是static的,才能找到 scope="prototype"

    />

    测试:

    public static void main(String[] args) {
          //调用getBean()时,返回随机数.如果没有指定factory-method,会返回StaticFactoryBean的实例,即返回工厂Bean的实例       XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("config.xml"));       System.out.println("我是IT学习者创建的实例:"+factory.getBean("random").toString());

    }

    第三种:单例模式(Singleton

    保证一个类仅有一个实例,并提供一个访问它的全局访问点。 
    spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。但没有从构造器级别去控制单例,这是因为spring管理的是是任意的java对象。 
    核心提示点:Spring下默认的bean均为singleton,可以通过singleton=“true|false” 或者 scope=“?”来指定

    第四种:适配器(Adapter

    在Spring的Aop中,使用的Advice(通知)来增强被代理类的功能。Spring实现这一AOP功能的原理就使用代理模式(1、JDK动态代理。2、CGLib字节码生成技术代理。)对类进行方法级别的切面增强,即,生成被代理类的代理类, 并在代理类的方法前,设置拦截器,通过执行拦截器重的内容增强了代理方法的功能,实现的面向切面编程。

    Adapter类接口:Target

    public interface AdvisorAdapter {

     

    boolean supportsAdvice(Advice advice);

     

          MethodInterceptor getInterceptor(Advisor advisor);

     

    MethodBeforeAdviceAdapter类,Adapter

    class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

     

          public boolean supportsAdvice(Advice advice) {

                return (advice instanceof MethodBeforeAdvice);

          }

     

          public MethodInterceptor getInterceptor(Advisor advisor) {

                MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();

          return new MethodBeforeAdviceInterceptor(advice);

          }

     

    }


    第五种:包装器(Decorator

    在我们的项目中遇到这样一个问题:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。我们以往在spring和hibernate框架中总是配置一个数据源,因而sessionFactory的dataSource属性总是指向这个数据源并且恒定不变,所有DAO在使用sessionFactory的时候都是通过这个数据源访问数据库。但是现在,由于项目的需要,我们的DAO在访问sessionFactory的时候都不得不在多个数据源中不断切换,问题就出现了:如何让sessionFactory在执行数据持久化的时候,根据客户的需求能够动态切换不同的数据源?我们能不能在spring的框架下通过少量修改得到解决?是否有什么设计模式可以利用呢? 
    首先想到在spring的applicationContext中配置所有的dataSource。这些dataSource可能是各种不同类型的,比如不同的数据库:Oracle、SQL Server、MySQL等,也可能是不同的数据源:比如apache 提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。然后sessionFactory根据客户的每次请求,将dataSource属性设置成不同的数据源,以到达切换数据源的目的。
    spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。 

    第六种:代理(Proxy

    为其他对象提供一种代理以控制对这个对象的访问。  从结构上来看和Decorator模式类似,但Proxy是控制,更像是一种对功能的限制,而Decorator是增加职责。 
    spring的Proxy模式在aop中有体现,比如JdkDynamicAopProxy和Cglib2AopProxy。 

    第七种:观察者(Observer

    定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
    spring中Observer模式常用的地方是listener的实现。如ApplicationListener。 

    第八种:策略(Strategy

    定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。 
    spring中在实例化对象的时候用到Strategy模式
    在SimpleInstantiationStrategy中有如下代码说明了策略模式的使用情况: 
     
    第九种:模板方法(Template Method

    定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
    Template Method模式一般是需要继承的。这里想要探讨另一种对Template Method的理解。spring中的JdbcTemplate,在用这个类时并不想去继承这个类,因为这个类的方法太多,但是我们还是想用到JdbcTemplate已有的稳定的、公用的数据库连接,那么我们怎么办呢?我们可以把变化的东西抽出来作为一个参数传入JdbcTemplate的方法中。但是变化的东西是一段代码,而且这段代码会用到JdbcTemplate中的变量。怎么办?那我们就用回调对象吧。在这个回调对象中定义一个操纵JdbcTemplate中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入这个回调对象到JdbcTemplate,从而完成了调用。这可能是Template Method不需要继承的另一种实现方式吧。 

    以下是一个具体的例子: 
    JdbcTemplate中的execute方法 
     
    JdbcTemplate执行execute方法 

    标签: ja

    展开全文
  • spring中用设计模式

    2016-12-06 21:09:47
    1.工厂模式,这个很明显,在各种BeanFactory以及ApplicationContext创建...3.代理模式,在Aop实现中用到了JDK的动态代理; 4.策略模式,第一个地方,加载资源文件的方式,使用了不同的方法,比如:ClassPathResour
  • spring中用到了9种设计模式,学习spring的源码以及设计模式,可以提高开发人员软件设计以及开发的水平,写出更加优雅的代码。 ‘ 文章目录简单工厂(非23种设计模式中的一种) 简单工厂(非23种设计模式中的一种) ...
  • Spring中所使用的设计模式

    万次阅读 多人点赞 2021-01-14 02:51:09
    Spring是一个非常优秀的开源框架,项目源码中所使用的设计模式随处可见,这篇文章主要记录一下Spring中常见的设计模式: (1)工厂模式:Spring使用工厂模式,通过BeanFactory和ApplicationContext来创建对象 (2...
  • SpringMVC中用到设计模式
  • 1.工厂设计模式Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。 2.代理设计模式Spring AOP功能的实现。 3.单例设计模式Spring中的bean默认都是单例的。 4.模板方法模式:Spring中的...
  • spring框架中用到了哪些设计模式 1、工厂设计模式 pring使用工厂模式可以通过 BeanFactory 或 ApplicationContext 创建 bean 对象。 两者对比: BeanFactory :延迟注入(使用某个 bean 的时候才会注入),相比于...
  • 前言: 关于设计模式的学习,如果仅仅是看一些概念或者小的demo很容易忘记并且对设计模式的理解也不是很深刻。其实结合一些常用的框架,工具类学习起来是比较快的,并且对于设计模式的...Spring中用到设计模式: ...
  • 下面举例介绍 Spring 中用到设计模式: 1. 模板设计模式 模板设计模式是一个模板方法规定了算法骨架,包括步骤一、步骤二、步骤三等,在子类中可以修改这些步骤方法。其中抽象方法叫钩子方法。 如:一个人的人生...
  • 工厂设计模式 : Spring使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。 代理设计模式 : Spring AOP 功能的实现。 单例设计模式 : Spring 中的 Bean 默认都是单例的。 模板方法模式 : Spring 中 ...
  • Spring框架中常用的设计模式详解

    万次阅读 多人点赞 2019-06-16 17:12:26
    一、浅谈控制反转(IOC)与依赖注入(DI) IOC(Inversion of Control)是Spring中一个非常重要的概念,它不是什么技术,而是一种解耦的设计...它不是一个模式,而是一种设计原则,但以下模式(但不限于)实现了IOC...
  • 准备几个自己熟悉的设计模式就够了。 单例模式 bean默认都是单例的 原型模式 指定作用域为prototype 工行模式 BeanFactory 模板方法 postProcessBeanFactory,onRefresh,initPropertyValue 策略模式 ...
  • 在软件开发中也常常遇到类似的情况,实现某一个功能有多个途径,此时可以使用一种设计模式来使得系统可以灵活地选择解决途径,也能够方便地增加新的解决途径。 一、策略模式 策略模式(Strategy Pattern):定义一...
  • 工厂模式Spring使用工厂模式通过BeanFactory创建Bean对象 代理模式Spring AOP功能基于代理模式实现 单例模式Spring中的Bean默认都是单例的 观察者模式Spring事件驱动模型就是观察者模式的应用 适配器...
  • 文章目录系列文章目录前言一、观察者模式二、模式角色三、示例四、优缺点1. 优点2. 缺点3. 适用环境参考文档 前言 建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出...
  • 3.代理模式SpringAop 用到了动态代理和CGLIB字节码生成技术 4.定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现--Application...
  • Spring使用工厂模式可以通过BeanFactory或ApplicationContext创建bean对象。 两者对比: BeanFactory:延迟注入(使用某个bean的时候才会注入),相比于BeanFactory来说会占用更少的内存,程序启动速度更快。 ...
  • 2、Spring 框架中都用到了哪些设计模式? 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例; 单例模式:Bean默认为单例模式。 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成...
  • (1)工厂模式Spring使用工厂模式,通过BeanFactory和ApplicationContext来创建对象 (2)单例模式:Bean默认为单例模式 (3)策略模式:例如Resource的实现类,针对不同的资源文件,实现了不同方式的资源获取...
  • 系列文章目录 文章目录系列文章目录前言一、模板模式二、主要角色1. AbstractTemplate(抽象模板):2. ConcreteTemplate(具体模板):三、...这种类型的设计模式属于行为型模式。 二、主要角色 1. AbstractTemplate
  • Spring中用到的九种设计模式一:单例 文章目录 Spring中用到的九种设计模式一:单例 前言 一、饿汉式 1. 饿汉式1 2. 饿汉式2 二、懒汉式 1. 懒汉式-非线程安全 2. 懒汉式-线程安全 3. 懒汉式-双重校验锁 隐患参考 三...
  • 在看源码的过程中发现用到的设计模式还是很多的,最近博主正好也学习了些设计模式,所以总结了下源码中所用设计模式,可能还有很多设计模式没找出来,有兴趣的可以一块来探讨呀
  • 系列文章目录 走出舒适圈,你会成为最好的自己 文章目录 系列文章目录 前言 一、静态代理与动态... 参考文档 Java代理模式及其应用 动态代理:JDK动态代理和CGLIB代理的区别 面试中关于Spring AOP和代理模式的那些事

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,122
精华内容 7,648
关键字:

spring中用到的设计模式

spring 订阅