spring 5-bean的生命周期和依赖注入

1.1 spring bean是如何创建的

spring中bean都是由spring框架来通过反射创建的;设想以下,如果需要自己实现一个bean管理的框架你会怎么设计?

  • BeanFactory :bean的创建工厂
  • IOC容器:bean创建后实例存储位置
  • BeanDefinition:bean的定义信息,告诉框架你要创建的类是什么、bean名称是什么、成员变量、初始化方法等等
  • bean的定义信息需要从配置文件或则java config中进行加载,则需要对应的BeanDefinitionReader 从文件中进行获取,根据不同的文件类型加载不同的Reader,生成统一的BeanDefinition
  • 循环依赖和三级缓存
  • 如何实现对应的后置处理,当我们想在bean实例创建前和创建后、及其创建需要执行的初始化方法时,该怎么做?需要给对应的实例属性赋值怎么做?
  • AOP怎么设计:对应的前置处理器和后置处理器怎么设计?
  • BeanPostProcessor:后置加载处理器,在bean实例化后可以进行一系列的初始化、属性赋值、执行方法的代理等等
  • Bean有对应的PostProcessor,那工厂类也可以设计对应的PostProcessor,可以进行一些工厂类的包装以及一些对应的event的监听和发布等等
Spring5源码解析

Bean工厂实现应该尽可能地支持标准Bean生命周期接口。全套初始化方法及其标准顺序为:

  1. BeanNameAware’s {@code setBeanName} (bean名称的包装,设置bean的名称)
  2. BeanClassLoaderAware’s {@code setBeanClassLoader} (bean类加载器的包装,设置bean classLoader)
  3. BeanFactoryAware’s {@code setBeanFactory} (bean工厂类的包装,设置bean的工厂类)
  4. EnvironmentAware’s {@code setEnvironment} (环境类包装,设置环境变量)
  5. EmbeddedValueResolverAware’s {@code setEmbeddedValueResolver} (嵌入值的处理包装,设置嵌入值处理器)
  6. ResourceLoaderAware’s {@code setResourceLoader}----仅适用于在应用程序上下文中运行时 (资源加载包装,设置资源加载器)
  7. ApplicationEventPublisherAware’s {@code setApplicationEventPublisher}----仅适用于在应用程序上下文中运行时(应用事件发布包装,设置应用事件的发布者)
  8. MessageSourceAware’s {@code setMessageSource}----仅适用于在应用程序上下文中运行时(国际化包装)
  9. ApplicationContextAware’s {@code setApplicationContext}----仅适用于在应用程序上下文中运行时(应用上下文包装,设置应用上下文)
  10. ServletContextAware’s {@code setServletContext}----仅适用于在web应用程序上下文中运行时(servlet上下文包装)
  11. {@code postProcessBeforeInitialization} methods of BeanPostProcessors (bean初始化之前的后置处理器)
  12. InitializingBean’s {@code afterPropertiesSet}(初始化bean,属性填充之后)
  13. a custom init-method definition (自定义的init方法)
  14. {@code postProcessAfterInitialization} methods of BeanPostProcessors(bean初始化之后的后置处理器);

上面阐述了beanfactory工厂化的实现bean生命周期的接口有哪些及其顺序;下面展示对应的应用上下文 refresh方法源码,查看时如何对应上面的顺序;源码如下:

  1. AbstractApplicationContext.refresh方法
@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      // 设置启动时间,active标识、上下文环境中的任何占位符属性源
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      // 告诉子类刷新内部beanFactory
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      // 上下文加载beanFactory ------step 3
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses
         // 在标准初始化之后修改应用程序上下文的内部bean工厂。所有bean定义都已加载,
         // 但还没有实例化bean。这允许在某些ApplicationContext实现中注册特殊的	                         beanpostprocessor等。
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         // 实例化和调用所有注册的BeanFactoryPostProcessor bean,如果给定了显式的顺序。
         // 必须在单例实例化之前调用。
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         // 实例化和注册所有BeanPostProcessor bean,如果给定的话,遵循显式顺序。
         // 必须在应用程序bean的任何实例化之前调用。
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         // 设置国际化 ------step8
         initMessageSource();

         // Initialize event multicaster for this context.
         // 设置应用上下文事件发布器 step7
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         // 添加将ApplicationListener实现为侦听器的bean。
         // 不会影响其他侦听器,可以在不使用bean的情况下添加其他侦听器。
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         // 完成这个上下文的bean工厂的初始化,初始化所有剩余的单例bean。
		 // 实例化所有剩余的(非延迟-init)单例。
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         // 调用LifecycleProcessor来完成这个上下文的刷新:onRefresh()方法并发布   ContextRefreshedEvent
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         // 销毁创建的实例
         destroyBeans();

         // Reset 'active' flag.
         // 重置 active 标识
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         // 重置spring中的缓存
         resetCommonCaches();
      }
   }
}
spring bean循环依赖

什么是循环依赖:beanA ->注入beanB ;beanB -> 注入beanA

循环依赖发生的前提:bean创建的scope为单例,采用set方式注入bean对象;

三级缓存: DefaultSingletonBeanRegistry 中:

/** Cache of singleton objects: bean name to bean instance. */
// 一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of singleton factories: bean name to ObjectFactory. */// 三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** Cache of early singleton objects: bean name to bean instance. */
// 二级缓存
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

循环依赖解决逻辑:

在这里插入图片描述

如图:能够使用对应的二级缓存解决对应的循环依赖问题;

但是当beanA或beanB如果是代理类(AOP)代理了,上面还适用吗?当然是不行的;

首先AOP是是实现在BeanPostProcessor中的,BeanPostProcessor是在bean 实例化之前调用,如果要实例化beanA,那么就应该实例化beanA被代理后的对象bean(jdk/cglib),否则一个bean名称出现了不同效果的实例,会出现意想不到的结果。

那么该如何解决代理类的实例化呢?那就是三级缓存;

首先查看bean创建的代码执行过程:

  1. resfresh—>AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)
  2. beanFactory.preInsantiateSingletons()
  3. DefaultListableBeanFactory.preInstantiateSingletons()
  4. AbstractBeanFactory.doGetBean
  5. DefaultSingletonBeanRegistry.getSingleton(String beanName, boolean allowEarlyReference)
  6. DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory)—>singletonFactory.getObject()
  7. AbstractAutowireCapableBeanFactory.createBean()—》doCreateBean—>反射创建实例
  8. AbstractAutowireCapableBeanFactory.populateBean
  9. AbstractAutowireCapableBeanFactory.initializeBean(beanName, exposedObject, mbd)–>applyBeanPostProcessorsBeforeInitialization–>invokeInitMethods—>applyBeanPostProcessorsAfterInitialization

在这里插入图片描述

举例说明:

A 注入B,B注入A,

1.实例化A开始

1.1 实例化A

1.1.1 生成实例A,存入三级缓存,删除二级缓存

1.1.2 填充B

1.1.2.1 实例化B

1.1.2.1.1 生成实例B,存入三级缓存,删除二级缓存

1.1.2.1.2 填充A ->

  • 从三级缓存中取出A,执行createBean,存入二级缓存,删除三级缓存
  • 填充A结束
  • B初始化等操作

1.1.2.2 B存入一级缓存,删除二三缓存–填充B结束

1.2A 初始化等操作, A存入一级缓存,删除二三级缓存

/**
 * Return the (raw) singleton object registered under the given name.
 * <p>Checks already instantiated singletons and also allows for an early
 * reference to a currently created singleton (resolving a circular reference).
 * @param beanName the name of the bean to look for
 * @param allowEarlyReference whether early references should be created or not
 * @return the registered singleton object, or {@code null} if none found
 */
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
         singletonObject = this.earlySingletonObjects.get(beanName);
         if (singletonObject == null && allowEarlyReference) {
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               singletonObject = singletonFactory.getObject();
               this.earlySingletonObjects.put(beanName, singletonObject);
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}
1.2 spring bean 依赖注入的几种方式
1.3 spring bean 的生命周期

bean的生命周期从bean的创建可以看到,下面展示对应的执行顺序图,如下:

在这里插入图片描述

下面用代码实践来验证上面的执行顺序:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="orderService" class="com.lww.spring.service.OrderServiceImpl" init-method="initOrder" destroy-method="destroyOrder">
        <property name="id" value="1"></property>
        <property name="orderNo" value="NUM-001"></property>
    </bean>


    <bean id="customBeanFactoryProcessor" class="com.lww.spring.postProcess.CustomBeanFactoryProcessor"></bean>

    <bean id="customBeanPostProcessor" class="com.lww.spring.postProcess.CustomBeanPostProcessor"></bean>

    <bean id="cusInstantiationAwareBeanPostProcessorAdapter" class="com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter"></bean>


</beans>
package com.lww.spring.service;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;

import java.util.logging.Logger;

public class OrderServiceImpl implements OrderService, BeanNameAware , BeanFactoryAware, InitializingBean, DisposableBean {

    private final Logger logger = Logger.getLogger("OrderService");

    private String id;

    private String orderNo;

    private String orderName;

    private String je;

    public OrderServiceImpl(){
        logger.info("step6:----创建bean的实例----------");

    }

    @Override
    public void getInfo() {
        logger.info("id:"+id+",orderNo:"+orderNo+",orderName:"+orderName+",je:"+je);
    }

    public void initOrder(){
        logger.info("step13:----执行init-method:OrderServiceImpl-----initOrder()----------");
    }

    public void destroyOrder(){
        logger.info("last step:----执行destroy-method:OrderServiceImpl-----destroyOrder()----------");

    }

    @Override
    public String addOrder(String info) {
        logger.info("addOrder:"+info);
        return "success";
    }

    @Override
    public void setBeanName(String name) {
        logger.info("step9:----执行BeanNameAware-----setBeanName()----------");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        logger.info("step10:----执行BeanFactoryAware-----setBeanFactory()----------");

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("step12:----执行InitializingBean-----afterPropertiesSet()----------");

    }

    @Override
    public void destroy() throws Exception {
        logger.info("销毁容器----执行DisposableBean-----destroy()----------");

    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        logger.info("step8:----属性填充(id)----------");
        this.id = id;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        logger.info("step8:----属性填充(orderNo)----------");

        this.orderNo = orderNo;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    public String getJe() {
        return je;
    }

    public void setJe(String je) {
        this.je = je;
    }


}
package com.lww.spring.postProcess;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

import java.util.logging.Logger;

/**
 * BeanFactoryPostProcessor 实现类,容器初始化第一步:实例化 step2: 执行postProcessBeanFactory
 */
public class CustomBeanFactoryProcessor implements BeanFactoryPostProcessor {

    private static final Logger logger = Logger.getLogger("CustomBeanFactoryProcessor");

    public CustomBeanFactoryProcessor(){
        logger.info("------step 1: 实例化eanFactoryPostProcessor");

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        logger.info("------step 2: 执行BeanFactoryPostProcessor.postProcessBeanFactory");
    }
}
package com.lww.spring.postProcess;

import com.lww.spring.service.OrderServiceImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.util.logging.Logger;

/**
 *   BeanPostProcessor step3 实例化BeanPostProcessor ;step 11: 执行postProcessBeforeInitialization;
 *   step 14 :执行postProcessAfterInitialization
 */
public class CustomBeanPostProcessor implements BeanPostProcessor {

    private static final Logger logger = Logger.getLogger("CustomBeanPostProcessor");

    public CustomBeanPostProcessor(){
        logger.info("------step 3: 实例化BeanPostProcessor");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        logger.info("------step 11: 执行BeanPostProcessor.postProcessBeforeInitialization");
        if(beanName.equals("orderService")){
            OrderServiceImpl orderService = (OrderServiceImpl) bean;
            logger.info("--------------------设置属性orderName");
            orderService.setOrderName("订单名称");
            logger.info("--------------------设置属性id为2");
            orderService.setId("2");

        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        logger.info("------step 14: 执行BeanPostProcessor.postProcessAfterInitialization");
        if(beanName.equals("orderService")){
            OrderServiceImpl orderService = (OrderServiceImpl) bean;
            orderService.getInfo();
            logger.info("--------------------设置属性je为100");
            orderService.setJe("100.00");
        }
        return bean;
    }
}
package com.lww.spring.postProcess;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

import java.util.logging.Logger;

/**
 * step4 实例化InstantiationAwareBeanPostProcessorAdapter
 * step5 执行postProcessBeforeInstantiation
 * step7 执行postProcessProperties
 * step14 执行postProcessAfterInitialization
 */
public class CusInstantiationAwareBeanPostProcessorAdapter extends InstantiationAwareBeanPostProcessorAdapter {

    private static final Logger logger = Logger.getLogger("CusInstantiationAwareBeanPostProcessorAdapter");


    public CusInstantiationAwareBeanPostProcessorAdapter(){
        logger.info("------step 4: 实例化InstantiationAwareBeanPostProcessorAdapter");

    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        logger.info("------step 5: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation");
        return super.postProcessBeforeInstantiation(beanClass, beanName);
    }


    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        logger.info("------step 7: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessProperties");
        return super.postProcessProperties(pvs, bean, beanName);
    }


    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        logger.info("------ step15: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInitialization");
        return super.postProcessAfterInitialization(bean, beanName);
    }
}
package com.lww.spring;

import com.lww.spring.service.OrderService;
import com.lww.spring.service.UserService;
import com.lww.spring.service.UserServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.logging.Logger;

public class CustomSpApplication {

    private static final Logger logger = Logger.getLogger("CustomSpApplication");

    public static void main(String[] args) {
        logger.info("-------------初始化容器-------------");
        ClassPathXmlApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring.xml");

        OrderService orderService  = (OrderService) applicationContext.getBean("orderService");
        orderService.getInfo();
        logger.info("-------------开始销毁容器-------------");
        applicationContext.registerShutdownHook();
    }


}
// 控制台打印如下:
八月 27, 2020 10:47:20 下午 com.lww.spring.CustomSpApplication main
信息: -------------初始化容器-------------
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanFactoryProcessor <init>
信息: ------step 1: 实例化eanFactoryPostProcessor
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanFactoryProcessor postProcessBeanFactory
信息: ------step 2: 执行BeanFactoryPostProcessor.postProcessBeanFactory
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor <init>
信息: ------step 3: 实例化BeanPostProcessor
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter <init>
信息: ------step 4: 实例化InstantiationAwareBeanPostProcessorAdapter
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter postProcessBeforeInstantiation
信息: ------step 5: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl <init>
信息: step6:----创建bean的实例----------
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter postProcessProperties
信息: ------step 7: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessProperties
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setId
信息: step8:----属性填充(id)----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setOrderNo
信息: step8:----属性填充(orderNo)----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setBeanName
信息: step9:----执行BeanNameAware-----setBeanName()----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setBeanFactory
信息: step10:----执行BeanFactoryAware-----setBeanFactory()----------
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessBeforeInitialization
信息: ------step 11: 执行BeanPostProcessor.postProcessBeforeInitialization
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessBeforeInitialization
信息: --------------------设置属性orderName
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessBeforeInitialization
信息: --------------------设置属性id为2
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setId
信息: step8:----属性填充(id)----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl afterPropertiesSet
信息: step12:----执行InitializingBean-----afterPropertiesSet()----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl initOrder
信息: step13:----执行init-method:OrderServiceImpl-----initOrder()----------
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessAfterInitialization
信息: ------step 14: 执行BeanPostProcessor.postProcessAfterInitialization
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl getInfo
信息: id:2,orderNo:NUM-001,orderName:订单名称,je:null
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessAfterInitialization
信息: --------------------设置属性je为100
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter postProcessAfterInitialization
信息: ------ step15: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInitialization
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl getInfo
信息: id:2,orderNo:NUM-001,orderName:订单名称,je:100.00
八月 27, 2020 10:47:21 下午 com.lww.spring.CustomSpApplication main
信息: -------------开始销毁容器-------------
销毁容器----执行DisposableBean-----destroy()----------
last step:----执行destroy-method:OrderServiceImpl-----destroyOrder()----------
    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值