Spring Bean 生命周期和Spring 中的设计模式

Spring Bean 生命周期

  • Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean
    在这里插入图片描述
  1. Spring 容器 从 XML 文件中读取 Bean 的定义,并实例化 Bean。
  2. Spring 根据 Bean 的定义填充所有的属性。
  3. 如果 Bean 实现了 BeanNameAware 接口,Spring 传递 bean 的 ID 到 setBeanName 方法。
  4. 如果 Bean 实现了 BeanFactoryAware 接口, Spring 传递 beanfactory 给 setBeanFactory 方法。
  5. 如果有任何与 bean 相关联的 BeanPostProcessors,Spring 会在 postProcesserBeforeInitialization()方 法内调用它们。
  6. 如果 bean 实现 IntializingBean 了,调用它的 afterPropertySet 方法,如果 bean 声明了初始化方法,调 用此初始化方法。
  7. 如果有 BeanPostProcessors 和 bean 关联,这些 bean 的 postProcessAfterInitialization() 方法将被调 用。
  8. 如果 bean 实现了 DisposableBean,它将调用 destroy()方法。

注意: 有两个重要的 bean 生命周期方法,第一个是 setup() , 它是在容器加载 bean 的时候被调用。第二个方法是 teardown()它是在容器卸载类的时候被调用。 The bean 标签有两个重要的属性 init-method 和destroy-method。使用它们你可以自己定制初始化和注销方 法。它们也有相应的注解@PostConstruct和@PreDestroy。


Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

  1. Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
  2. Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
  3. 容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
  4. 工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

Spring 中的设计模式

1. 代 理 模 式
  • Spring 中 两 种 代 理 方 式 , 若 目 标 对 象 实 现 了 若 干 接 口 , spring 使 用 JDK 的 java.lang.reflect.Proxy 类代理,若目标对象没有实现任何接口,spring 使用 CGLIB 库生成目标对象的子类。
  • 实现方式: AOP底层,就是动态代理模式的实现。
    • 动态代理:在内存中构建的,不需要手动编写代理类
    • 静态代理:需要手工编写代理类,代理类引用被代理对象。
  • 实现原理:
    • 切面在应用运行的时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象创建动态的创建一个代理对象。SpringAOP就是以这种方式织入切面的。
  • 织入:把切面应用到目标对象并创建新的代理对象的过程。
2. 单例模式
  • 在 spring 配置文件中定义的 bean 默认为单例模式。
  • Spring的依赖注入(包括lazy-init方式)都是发生在AbstractBeanFactory的getBean里。getBean的doGetBean方法调用getSingleton进行bean的创建。

分析getSingleton()方法

public Object getSingleton(String beanName){
    //参数true设置标识允许早期依赖
    return getSingleton(beanName,true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    //检查缓存中是否存在实例
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        //如果为空,则锁定全局变量并进行处理。
        synchronized (this.singletonObjects) {
            //如果此bean正在加载,则不处理
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {  
                //当某些方法需要提前初始化的时候则会调用addSingleFactory 方法将对应的ObjectFactory初始化策略存储在singletonFactories
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    //调用预先设定的getObject方法
                    singletonObject = singletonFactory.getObject();
                    //记录在缓存中,earlysingletonObjects和singletonFactories互斥
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

3. 模板方法模式
  • 用来解决代码重复的问题。 比如: RestTemplate, JmsTemplate, JpaTemplate。
  • 经典模板方法定义:
    • 父类定义了骨架(调用哪些方法及顺序),某些特定方法由子类实现
    • 最大的好处:代码复用,减少重复代码。除了子类要实现的特定方法,其他方法及方法调用顺序都在父类中预先写好了。
    • 所以父类模板方法中有两类方法:
      • 共同的方法:所有子类都会用到的代码
      • 不同的方法:子类要覆盖的方法,分为两种:
        • 抽象方法:父类中的是抽象方法,子类必须覆盖
        • 钩子方法:父类中是一个空方法,子类继承了默认也是空的
        • 注:为什么叫钩子,子类可以通过这个钩子(方法),控制父类,因为这个钩子实际是父类的方法(空方法)!
  • Spring模板方法模式实质:是模板方法模式和回调模式的结合,是Template Method不需要继承的另一种实现方式。Spring几乎所有的外接扩展都采用这种模式。
4. 前端控制器模式
  • Srping 提供了 DispatcherServlet 来对请求进行分发。
5. 视图帮助(View Helper )
  • Spring 提供了一系列的 JSP 标签,高效宏来辅助将分散的代码整合在视图里。
6. 依赖注入
  • 贯穿于 BeanFactory/ApplicationContext 接口的核心理念。
7. 工厂模式
  • 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口 来指向新创建的对象。Spring 中使用 BeanFactory 用来创建对象的实例。
  • 实现方式:FactoryBean接口。
  • 实现原理:实现了FactoryBean接口的bean是一类叫做factory的bean。其特点是,spring会在使用getBean()调用获得该bean时,会自动调用该bean的getObject()方法,所以返回的不是factory这个bean,而是这个bean.getOjbect()方法的返回值。

参考文章 :

  • https://www.cnblogs.com/zrtqsk/p/3735273.html
  • https://blog.csdn.net/caoxiaohong1005/article/details/80039656

你知道的越多,你不知道的越多。
有道无术,术尚可求,有术无道,止于术。
如有其它问题,欢迎大家留言,我们一起讨论,一起学习,一起进步

发布了193 篇原创文章 · 获赞 116 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40722827/article/details/104981967