一文搞定 Spring Bean 的创建全过程!

Java技术迷

共 70787字,需浏览 142分钟

 ·

2021-05-23 20:27

作者 | x1aoda1

来源 | www.cnblogs.com/darope/p/13917264.html

1.1 Spring测试环境搭建

Spring模块概览,绿色是模块,Spring中八大模块,黑色表示该模块包含的jar包(组件)。例如我们想要用IOC容器,也就是绿色的CoreContainer,我们需要导入Beans,Core,Context,SpEL(spring-expression)四个包。

Spring模块概览

  • Test:测试相关
  • Core Container:IOC容器
  • AOP:面向切面编程
  • Aspects:切面
  • Instrumenttation:跟JDK关联,一般不用
  • Messaging:消息服务,一般不用
  • Data Access/Integration:数据访问与集成(JDBC访问,Transaction事务,ORM对象关系映射,OXM和XML映射一般不用,JMS为Java消息服务Java-message-service一般不用)
  • Web:Web服务(WebSocket网络通信协议,Servlet, Web,Portlet一般不用)

最偷懒的方式,是直接导入Spring-Framework。但是可能导入不必要的包,导致项目打包后比较大

由于Spring-Content中的ApplicationContent是整个IOC的入口。我们导入Spring-context包即可

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.3.RELEASE</version>
</dependency>

我们导入spring-content后,默认会导入该组件的依赖jar,spring-content底层的依赖可以看到,实际上我们是导入了Core Container模块:

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.2.3.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.2.3.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.2.3.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.2.3.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

新建Spring配置文件spring.xml:

<?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">

    <!--注册一个对象,spring回自动创建这个对象-->
    <!--
    一个bean标签就表示一个对象
    id:这个对象的唯一标识
    class:注册对象的完全限定名
    -->
    <bean id="hello" class="com.xiaodai.service.Hello">
        <!--使用property标签给对象的属性赋值
        name:表示属性的名称
        value:表示属性的值
        -->
        <property name="id" value="1"></property>
        <property name="name" value="zhangsan"></property>
        <property name="age" value="18"></property>
    </bean>
</beans>

编写测试类:

import com.xiaodai.service.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Hello hello = applicationContext.getBean("hello", Hello.class);
        System.out.println(hello.getName());

    }

}

1.2 Debug容器创建过程

从测试类的new ClassPathXmlApplicationContext("spring.xml")开始debug,进入ClassPathXmlApplicationContext,可以看到:

 public ClassPathXmlApplicationContext(
   String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
   throws BeansException {

  super(parent);
  // 设置配置文件路径
  setConfigLocations(configLocations);
  if (refresh) {
          // 核心步骤
   refresh();
  }
 }

加载配置文件后,进入refresh()方法,该方法是容器初始化的核心步骤。该方法包含十三个方法:

        @Override
 public void refresh() throws BeansException, IllegalStateException {
  synchronized (this.startupShutdownMonitor) {
   // Prepare this context for refreshing.
   /** 
    * 准备刷新,做一些最基本的准备化工作
   **/
   prepareRefresh();

   // Tell the subclass to refresh the internal bean factory.
   /** 
    * 获得一个刷新的bean容器,实质就是获取工厂。
    * 加载xml等配置文件,用该文件产生的BeanDefinition来创建一个工厂
   **/
   ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

   // Prepare the bean factory for use in this context.
   /**
    * 准备bean工厂
   **/
   prepareBeanFactory(beanFactory);

   try {
    // Allows post-processing of the bean factory in context subclasses.
    // 后置增强,方便扩展
    postProcessBeanFactory(beanFactory);

    // Invoke factory processors registered as beans in the context.
    // 实例化并且执行BeanFactoryPostProcessors
    invokeBeanFactoryPostProcessors(beanFactory);

    // Register bean processors that intercept bean creation.
    // 实例化并且注册所有的BeanPostProcessor
    registerBeanPostProcessors(beanFactory);

    // Initialize message source for this context.
    // 国际化设置,一般用不到
    initMessageSource();

    // Initialize event multicaster for this context.
    // 初始化应用程序的多波器和广播器
    initApplicationEventMulticaster();

    // Initialize other special beans in specific context subclasses.
    // 空方法,预留给子类做扩展
    onRefresh();

    // Check for listener beans and register them.
    // 注册监听器
    registerListeners();

    // Instantiate all remaining (non-lazy-init) singletons.
    // 工作中常用,面试常问。实例化所有非懒加载的实例对象
    finishBeanFactoryInitialization(beanFactory);

    // Last step: publish corresponding event.
    // 完成刷新
    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.
    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...
    resetCommonCaches();
   }
  }
 }

1.3 AbstractApplicationContext的refresh()包含的13个方法分析

结合概览图一个一个方法分析:

Bean工厂实例化Bean概览图

方法1:prepareRefresh() => 准备工作

准备刷新,做一些最基本的准备化工作

 protected void prepareRefresh() {
  // Switch to active.
  // 设置开始时间
  this.startupDate = System.currentTimeMillis();
  // 关闭状态设置为false
  this.closed.set(false);
  // 活跃状态设置为true
  this.active.set(true);

        // 打印日志
  if (logger.isDebugEnabled()) {
   if (logger.isTraceEnabled()) {
    logger.trace("Refreshing " + this);
   }
   else {
    logger.debug("Refreshing " + getDisplayName());
   }
  }

  // Initialize any placeholder property sources in the context environment.
  // 初始化属性资源
  initPropertySources();

  // Validate that all properties marked as required are resolvable:
  // see ConfigurablePropertyResolver#setRequiredProperties
  // 获取环境信息,验证属性信息
  getEnvironment().validateRequiredProperties();

  // Store pre-refresh
  // 存储预刷新的一些应用信息的监听器
  ApplicationListeners...
  if (this.earlyApplicationListeners == null) {
   this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
  }
  else {
   // Reset local application listeners to pre-refresh state.
   this.applicationListeners.clear();
   this.applicationListeners.addAll(this.earlyApplicationListeners);
  }

  // Allow for the collection of early ApplicationEvents,
  // to be published once the multicaster is available...
  // 创建一些监听器事件的集合
  this.earlyApplicationEvents = new LinkedHashSet<>();
 }

总结:1.设置启动事件 2.设置关闭活跃的状态 3.获取环境对象并设置属性值 4.设置监听器以及需要发布事件的集合。

重要的点:

  • 获取环境信息,验证属性信息,getEnvironment().validateRequiredProperties();
  • 存储预刷新的一些应用信息的监听器,在Spring中是空实现,但是SpringBoot中,是有具体的值的

方法2:obtainFreshBeanFactory() => 获得一个刷新的bean容器

获得一个刷新的bean容器,实质就是获取工厂。创建容器对象DefaultListableBeanFactory;加载xml配置文件的属性到当前的工厂中,最重要的就是BeanDefinition

Bean工厂实例继承关系图

AbstractRefreshableApplicationContext:

    // 只要进到这个方法,那么我们创建的一定是一个新的工厂
 @Override
 protected final void refreshBeanFactory() throws BeansException {
  if (hasBeanFactory()) {
      // 如果存在先销毁,后关闭
   destroyBeans();
   closeBeanFactory();
  }
  try {
      // 创建bean工厂,这里使用的就是DefaultListableBeanFactory。此时创建的工厂里面的属性值都是默认值
   DefaultListableBeanFactory beanFactory = createBeanFactory();
   // 序列化id
   beanFactory.setSerializationId(getId());
   // 设置一些属性值
   customizeBeanFactory(beanFactory);
   // 加载bean的定义属性值。该方法有很多重载,非常复杂,核心是do操作
   // 完成配置文件或者配置类文件的加载
   loadBeanDefinitions(beanFactory);
   synchronized (this.beanFactoryMonitor) {
    this.beanFactory = beanFactory;
   }
  }
  catch (IOException ex) {
   throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
  }
 }

方法3:prepareBeanFactory(beanFactory) => 准备(初始化)Bean工厂

为方法2拿到的工厂,设置某些具体的值

 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  // Tell the internal bean factory to use the context's class loader etc.
  // 为bean工厂设置类加载器
  beanFactory.setBeanClassLoader(getClassLoader());
  // 设置SPEL解析器
  beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

  // Configure the bean factory with context callbacks.
  // 添加一个BeanPostProcessor
  beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  // 忽略对应接口的实现
  beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
  beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
  beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
  beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
  beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
  beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

  // BeanFactory interface not registered as resolvable type in a plain factory.
  // MessageSource registered (and found for autowiring) as a bean.
        // 注册一些依赖
  beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
  beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  beanFactory.registerResolvableDependency(ApplicationContext.class, this);

  // Register early post-processor for detecting inner beans as
  // ApplicationListeners添加一个BeanPostProcessor增强器
  ApplicationListeners.
  beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

  // Detect a LoadTimeWeaver and prepare for weaving, if found.
  if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
   beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
   // Set a temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  }

  // Register default environment beans.
  if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
   beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
  }
  if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
   beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
  }
  if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
   beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
  }
 }

方法4:postProcessBeanFactory(beanFactory) => 后置增强Bean(扩展实现)

空方法,方便扩展

方法5:invokeBeanFactoryPostProcessors(beanFactory) => 执行BFPP

实例化并且执行BeanFactoryPostProcessors

 /**
  * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
  * respecting explicit order if given.
  * <p>Must be called before singleton instantiation.
  * 单例对象之前一定调用,因为单例bean创建后就只有一份
  */
 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

  // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
  // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
  if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
   beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
   beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  }
 }

方法6:registerBeanPostProcessors(beanFactory) => 注册BPP

实例化并且注册所有的BeanPostProcessor。实例化Bean之前的准备工作

 /**
  * Instantiate and register all BeanPostProcessor beans,
  * respecting explicit order if given.
  * <p>Must be called before any instantiation of application beans.
  */
 protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
 }

方法7:initMessageSource() => 国际化设置

方法8:initApplicationEventMulticaster() => 初始化应用程序的多波器和广播器

也属于准备工作

方法9:onRefresh() => 预留给子类做扩展

空方法

方法10:registerListeners() => 注册监听器

也属于准备工作

 /**
  * Add beans that implement ApplicationListener as listeners.
  * Doesn't affect other listeners, which can be added without being beans.
  */
 protected void registerListeners() {
  // Register statically specified listeners first.
  for (ApplicationListener<?> listener : getApplicationListeners()) {
   getApplicationEventMulticaster().addApplicationListener(listener);
  }

  // Do not initialize FactoryBeans here: We need to leave all regular beans
  // uninitialized to let post-processors apply to them!
  String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
  for (String listenerBeanName : listenerBeanNames) {
   getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  }

  // Publish early application events now that we finally have a multicaster...
  Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
  this.earlyApplicationEvents = null;
  if (earlyEventsToProcess != null) {
   for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
    getApplicationEventMulticaster().multicastEvent(earlyEvent);
   }
  }
 }

方法11:finishBeanFactoryInitialization(beanFactory) => 实例化所有单例对象

面试常问,工作常用。过程比较复杂

 /**
  * Finish the initialization of this context's bean factory,
  * initializing all remaining singleton beans.
  */
 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  // Initialize conversion service for this context.
  /**
   * 把类型转化操作,设置到当前的beanFactory里面去
  **/
  if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
    beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
   beanFactory.setConversionService(
     beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
  }

  // Register a default embedded value resolver if no bean post-processor
  // (such as a PropertyPlaceholderConfigurer bean) registered any before:
  // at this point, primarily for resolution in annotation attribute values.
  /**
   * 判断当前的beanFactory有没有内置的值处理器
  **/
  if (!beanFactory.hasEmbeddedValueResolver()) {
   beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
  }

  // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
  /**
   * 织入Aware
  **/
  String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
  for (String weaverAwareName : weaverAwareNames) {
   getBean(weaverAwareName);
  }

  // Stop using the temporary ClassLoader for type matching.
  // 设置类加载器
  beanFactory.setTempClassLoader(null);

  // Allow for caching all bean definition metadata, not expecting further changes.
  /**
   * 冻结:某些bean不需要进行修改操作了,放入
  **/
  beanFactory.freezeConfiguration();

  // Instantiate all remaining (non-lazy-init) singletons.
  /**
   * 实例化所有非懒加载的实例对象(重要)
  **/
  beanFactory.preInstantiateSingletons();
 }

实例化所有非懒加载的实例对象方法:

 @Override
 public void preInstantiateSingletons() throws BeansException {
  if (logger.isTraceEnabled()) {
   logger.trace("Pre-instantiating singletons in " + this);
  }

  // Iterate over a copy to allow for init methods which in turn register new bean definitions.
  // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
  /**
   * 拿到所有注册bean的名称
   **/
  List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

  // Trigger initialization of all non-lazy singleton beans...
  // 循环去创建我们需要的单例对象
  for (String beanName : beanNames) {
      // 拿到bean的定义信息,就是我们在xml配置文件里面指定的一些属性
   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
   // 是否是抽象的,是否是单例的,是否是懒加载的
   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
       // 判断当前类是否实现了factoryBean接口。一般没实现,直接进入下面的getBean
    if (isFactoryBean(beanName)) {
     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
     if (bean instanceof FactoryBean) {
      final FactoryBean<?> factory = (FactoryBean<?>) bean;
      boolean isEagerInit;
      if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
       isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
           ((SmartFactoryBean<?>) factory)::isEagerInit,
         getAccessControlContext());
      }
      else {
       isEagerInit = (factory instanceof SmartFactoryBean &&
         ((SmartFactoryBean<?>) factory).isEagerInit());
      }
      if (isEagerInit) {
       getBean(beanName);
      }
     }
    }
    else {
        // 通过beanName。拿到bean
     getBean(beanName);
    }
   }
  }

  // Trigger post-initialization callback for all applicable beans...
  for (String beanName : beanNames) {
   Object singletonInstance = getSingleton(beanName);
   if (singletonInstance instanceof SmartInitializingSingleton) {
    final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    if (System.getSecurityManager() != null) {
     AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
      smartSingleton.afterSingletonsInstantiated();
      return null;
     }, getAccessControlContext());
    }
    else {
     smartSingleton.afterSingletonsInstantiated();
    }
   }
  }
 }

重要方法:

  • getMergedLocalBeanDefinition
 /**
  * Return a merged RootBeanDefinition, traversing the parent bean definition
  * if the specified bean corresponds to a child bean definition.
  * @param beanName the name of the bean to retrieve the merged definition for
  * @return a (potentially merged) RootBeanDefinition for the given bean
  * @throws NoSuchBeanDefinitionException if there is no bean with the given name
  * @throws BeanDefinitionStoreException in case of an invalid bean definition
  */
  // 返回一个合并好的RootBeanDefinition。整合子类和父类
 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
  // Quick check on the concurrent map first, with minimal locking.
  RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
  if (mbd != null && !mbd.stale) {
   return mbd;
  }
  return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
 }
  • getBean() => doGetBean()
 /**
  * Return an instance, which may be shared or independent, of the specified bean.
  * @param name the name of the bean to retrieve
  * @param requiredType the required type of the bean to retrieve
  * @param args arguments to use when creating a bean instance using explicit arguments
  * (only applied when creating a new instance as opposed to retrieving an existing one)
  * @param typeCheckOnly whether the instance is obtained for a type check,
  * not for actual use
  * @return an instance of the bean
  * @throws BeansException if the bean could not be created
  */
 @SuppressWarnings("unchecked")
 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
   @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        // 获取beanName
  final String beanName = transformedBeanName(name);
  Object bean;

  // Eagerly check singleton cache for manually registered singletons.
  // 单例检查,如果一级,二级,三级缓存中存在该Bean,直接获取到了
  Object sharedInstance = getSingleton(beanName);
  if (sharedInstance != null && args == null) {
   if (logger.isTraceEnabled()) {
    if (isSingletonCurrentlyInCreation(beanName)) {
     logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
       "' that is not fully initialized yet - a consequence of a circular reference");
    }
    else {
     logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
    }
   }
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  }

  else {
   // Fail if we're already creating this bean instance:
   // We'
re assumably within a circular reference.
   // 如果是单例对象的话,尝试解决循环依赖问题
   if (isPrototypeCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
   }

   // Check if bean definition exists in this factory.
   // 获取父类容器
   BeanFactory parentBeanFactory = getParentBeanFactory();
   if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    // Not found -> check parent.
    String nameToLookup = originalBeanName(name);
    if (parentBeanFactory instanceof AbstractBeanFactory) {
     return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
       nameToLookup, requiredType, args, typeCheckOnly);
    }
    else if (args != null) {
     // Delegation to parent with explicit args.
     return (T) parentBeanFactory.getBean(nameToLookup, args);
    }
    else if (requiredType != null) {
     // No args -> delegate to standard getBean method.
     return parentBeanFactory.getBean(nameToLookup, requiredType);
    }
    else {
     return (T) parentBeanFactory.getBean(nameToLookup);
    }
   }

            // 标志位。如果不是类型检查,表示要创建bean,此处在集合中做一个记录
   if (!typeCheckOnly) {
    markBeanAsCreated(beanName);
   }

   try {
       // 获取beanDefinition
    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    // 检测beanDefinition
    checkMergedBeanDefinition(mbd, beanName, args);

    // Guarantee initialization of beans that the current bean depends on.
    // 检查当前的bean是否有其他依赖的bean
    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) {
        // 如果有依赖的bean,我们要先递归解决其他依赖的bean
     for (String dep : dependsOn) {
      if (isDependent(beanName, dep)) {
       throw new BeanCreationException(mbd.getResourceDescription(), beanName,
         "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
      }
      registerDependentBean(dep, beanName);
      try {
       getBean(dep);
      }
      catch (NoSuchBeanDefinitionException ex) {
       throw new BeanCreationException(mbd.getResourceDescription(), beanName,
         "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
      }
     }
    }

    // Create bean instance.
    // 是否是单例的
    if (mbd.isSingleton()) {
     sharedInstance = getSingleton(beanName, () -> {
      try {
       return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
       // Explicitly remove instance from singleton cache: It might have been put there
       // eagerly by the creation process, to allow for circular reference resolution.
       // Also remove any beans that received a temporary reference to the bean.
       destroySingleton(beanName);
       throw ex;
      }
     });
     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

    else if (mbd.isPrototype()) {
     // It's a prototype -> create a new instance.
     Object prototypeInstance = null;
     try {
      beforePrototypeCreation(beanName);
      prototypeInstance = createBean(beanName, mbd, args);
     }
     finally {
      afterPrototypeCreation(beanName);
     }
     bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    }

    else {
     String scopeName = mbd.getScope();
     final Scope scope = this.scopes.get(scopeName);
     if (scope == null) {
      throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
     }
     try {
      Object scopedInstance = scope.get(beanName, () -> {
       beforePrototypeCreation(beanName);
       try {
        return createBean(beanName, mbd, args);
       }
       finally {
        afterPrototypeCreation(beanName);
       }
      });
      bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
     }
     catch (IllegalStateException ex) {
      throw new BeanCreationException(beanName,
        "Scope '" + scopeName + "' is not active for the current thread; consider " +
        "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
        ex);
     }
    }
   }
   catch (BeansException ex) {
    cleanupAfterBeanCreationFailure(beanName);
    throw ex;
   }
  }

  // Check if required type matches the type of the actual bean instance.
  if (requiredType != null && !requiredType.isInstance(bean)) {
   try {
    T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
    if (convertedBean == null) {
     throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }
    return convertedBean;
   }
   catch (TypeMismatchException ex) {
    if (logger.isTraceEnabled()) {
     logger.trace("Failed to convert bean '" + name + "' to required type '" +
       ClassUtils.getQualifiedName(requiredType) + "'", ex);
    }
    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
   }
  }
  return (T) bean;
 }
  • getSingleton
 /**
  * Return the (raw) singleton object registered under the given name,
  * creating and registering a new one if none registered yet.
  * @param beanName the name of the bean
  * @param singletonFactory the ObjectFactory to lazily create the singleton
  * with, if necessary
  * @return the registered singleton object
  */
 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  Assert.notNull(beanName, "Bean name must not be null");
  synchronized (this.singletonObjects) {
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null) {
    if (this.singletonsCurrentlyInDestruction) {
     throw new BeanCreationNotAllowedException(beanName,
       "Singleton bean creation not allowed while singletons of this factory are in destruction " +
       "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
    }
    if (logger.isDebugEnabled()) {
     logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
    }
    beforeSingletonCreation(beanName);
    boolean newSingleton = false;
    boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
    if (recordSuppressedExceptions) {
     this.suppressedExceptions = new LinkedHashSet<>();
    }
    try {
        // 实际上就是调用了CreateBean
     singletonObject = singletonFactory.getObject();
     newSingleton = true;
    }
    catch (IllegalStateException ex) {
     // Has the singleton object implicitly appeared in the meantime ->
     // if yes, proceed with it since the exception indicates that state.
     singletonObject = this.singletonObjects.get(beanName);
     if (singletonObject == null) {
      throw ex;
     }
    }
    catch (BeanCreationException ex) {
     if (recordSuppressedExceptions) {
      for (Exception suppressedException : this.suppressedExceptions) {
       ex.addRelatedCause(suppressedException);
      }
     }
     throw ex;
    }
    finally {
     if (recordSuppressedExceptions) {
      this.suppressedExceptions = null;
     }
     afterSingletonCreation(beanName);
    }
    if (newSingleton) {
     addSingleton(beanName, singletonObject);
    }
   }
   return singletonObject;
  }
 }
  • doCreateBean => 通过上方法的singletonObject = singletonFactory.getObject();进入的
 /**
  * Actually create the specified bean. Pre-creation processing has already happened
  * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
  * <p>Differentiates between default bean instantiation, use of a
  * factory method, and autowiring a constructor.
  * @param beanName the name of the bean
  * @param mbd the merged bean definition for the bean
  * @param args explicit arguments to use for constructor or factory method invocation
  * @return a new instance of the bean
  * @throws BeanCreationException if the bean could not be created
  * @see #instantiateBean
  * @see #instantiateUsingFactoryMethod
  * @see #autowireConstructor
  */
 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
   throws BeanCreationException {

  // Instantiate the bean.
  BeanWrapper instanceWrapper = null;
  if (mbd.isSingleton()) {
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  }
  if (instanceWrapper == null) {
      /**
       * 核心的创建实例化Bean的过程
      **/
   instanceWrapper = createBeanInstance(beanName, mbd, args);
  }
  final Object bean = instanceWrapper.getWrappedInstance();
  Class<?> beanType = instanceWrapper.getWrappedClass();
  if (beanType != NullBean.class) {
   mbd.resolvedTargetType = beanType;
  }

  // Allow post-processors to modify the merged bean definition.
  synchronized (mbd.postProcessingLock) {
   if (!mbd.postProcessed) {
    try {
     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    }
    catch (Throwable ex) {
     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
       "Post-processing of merged bean definition failed", ex);
    }
    mbd.postProcessed = true;
   }
  }

  // Eagerly cache singletons to be able to resolve circular references
  // even when triggered by lifecycle interfaces like BeanFactoryAware.
  boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    isSingletonCurrentlyInCreation(beanName));
    
  /**
   * 解决循环依赖。使用三级缓存
  **/
  if (earlySingletonExposure) {
   if (logger.isTraceEnabled()) {
    logger.trace("Eagerly caching bean '" + beanName +
      "' to allow for resolving potential circular references");
   }
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  }

  // Initialize the bean instance.
  Object exposedObject = bean;
  try {
      /**
       * 填充属性,上文的实例化只是默认属性值。填充属性是初始化的第一步,第二步是执行init方法
      **/
   populateBean(beanName, mbd, instanceWrapper);
   /**
    * 执行init方法
   **/
   exposedObject = initializeBean(beanName, exposedObject, mbd);
  }
  catch (Throwable ex) {
   if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    throw (BeanCreationException) ex;
   }
   else {
    throw new BeanCreationException(
      mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
   }
  }

  if (earlySingletonExposure) {
   Object earlySingletonReference = getSingleton(beanName, false);
   if (earlySingletonReference != null) {
    if (exposedObject == bean) {
     exposedObject = earlySingletonReference;
    }
    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
     String[] dependentBeans = getDependentBeans(beanName);
     Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
     for (String dependentBean : dependentBeans) {
      if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
       actualDependentBeans.add(dependentBean);
      }
     }
     if (!actualDependentBeans.isEmpty()) {
      throw new BeanCurrentlyInCreationException(beanName,
        "Bean with name '" + beanName + "' has been injected into other beans [" +
        StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
        "] in its raw version as part of a circular reference, but has eventually been " +
        "wrapped. This means that said other beans do not use the final version of the " +
        "bean. This is often the result of over-eager type matching - consider using " +
        "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
     }
    }
   }
  }

  // Register bean as disposable.
  try {
      /**
       * 需要销毁的时候,销毁的钩子函数
      **/
   registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }
  catch (BeanDefinitionValidationException ex) {
   throw new BeanCreationException(
     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }

  return exposedObject;
 }

面试题:为甚么循环依赖的解决要使用三级缓存?

  • createBeanInstance => 核心的创建和实例化bean的过程,由doCreateBean调用

大量的反射出现在该方法中,用来创建对象

 /**
  * Create a new instance for the specified bean, using an appropriate instantiation strategy:
  * factory method, constructor autowiring, or simple instantiation.
  * @param beanName the name of the bean
  * @param mbd the bean definition for the bean
  * @param args explicit arguments to use for constructor or factory method invocation
  * @return a BeanWrapper for the new instance
  * @see #obtainFromSupplier
  * @see #instantiateUsingFactoryMethod
  * @see #autowireConstructor
  * @see #instantiateBean
  */
 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
  // Make sure bean class is actually resolved at this point.
  Class<?> beanClass = resolveBeanClass(mbd, beanName);

  if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
   throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
  }

  Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
  if (instanceSupplier != null) {
   return obtainFromSupplier(instanceSupplier, beanName);
  }

  if (mbd.getFactoryMethodName() != null) {
   return instantiateUsingFactoryMethod(beanName, mbd, args);
  }

  // Shortcut when re-creating the same bean...
  boolean resolved = false;
  boolean autowireNecessary = false;
  if (args == null) {
   synchronized (mbd.constructorArgumentLock) {
    if (mbd.resolvedConstructorOrFactoryMethod != null) {
     resolved = true;
     autowireNecessary = mbd.constructorArgumentsResolved;
    }
   }
  }
  if (resolved) {
   if (autowireNecessary) {
    return autowireConstructor(beanName, mbd, null, null);
   }
   else {
    return instantiateBean(beanName, mbd);
   }
  }

  // Candidate constructors for autowiring?
  // 构造器
  Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
    mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
   return autowireConstructor(beanName, mbd, ctors, args);
  }

  // Preferred constructors for default construction?
  ctors = mbd.getPreferredConstructors();
  if (ctors != null) {
   return autowireConstructor(beanName, mbd, ctors, null);
  }

  // No special handling: simply use no-arg constructor.
  /**
   * 默认无参构造
   **/
  return instantiateBean(beanName, mbd);
 }
  • instantiateBean(beanName, mbd) => 默认无参构造
 /**
  * Instantiate the given bean using its default constructor.
  * @param beanName the name of the bean
  * @param mbd the bean definition for the bean
  * @return a BeanWrapper for the new instance
  */
 protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
  try {
   Object beanInstance;
   final BeanFactory parent = this;
   if (System.getSecurityManager() != null) {
    beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
            // 实例化只会分配内存空间,设置默认值
      getInstantiationStrategy().instantiate(mbd, beanName, parent),
      getAccessControlContext());
   }
   else {
    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
   }
   BeanWrapper bw = new BeanWrapperImpl(beanInstance);
   initBeanWrapper(bw);
   return bw;
  }
  catch (Throwable ex) {
   throw new BeanCreationException(
     mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
  }
 }
  • instantiate
 @Override
 public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
  // Don't override the class with CGLIB if no overrides.
  if (!bd.hasMethodOverrides()) {
   Constructor<?> constructorToUse;
   synchronized (bd.constructorArgumentLock) {
    constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
    if (constructorToUse == null) {
     final Class<?> clazz = bd.getBeanClass();
     if (clazz.isInterface()) {
      throw new BeanInstantiationException(clazz, "Specified class is an interface");
     }
     try {
      if (System.getSecurityManager() != null) {
       constructorToUse = AccessController.doPrivileged(
         (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
      }
      else {
       constructorToUse = clazz.getDeclaredConstructor();
      }
      bd.resolvedConstructorOrFactoryMethod = constructorToUse;
     }
     catch (Throwable ex) {
      throw new BeanInstantiationException(clazz, "No default constructor found", ex);
     }
    }
   }
   return BeanUtils.instantiateClass(constructorToUse);
  }
  else {
   // Must generate CGLIB subclass.
   return instantiateWithMethodInjection(bd, beanName, owner);
  }
 }
  • BeanUtils.instantiateClass => 通过构造器反射创建bean
 /**
  * Convenience method to instantiate a class using the given constructor.
  * <p>Note that this method tries to set the constructor accessible if given a
  * non-accessible (that is, non-public) constructor, and supports Kotlin classes
  * with optional parameters and default values.
  * @param ctor the constructor to instantiate
  * @param args the constructor arguments to apply (use {@code null} for an unspecified
  * parameter, Kotlin optional parameters and Java primitive types are supported)
  * @return the new instance
  * @throws BeanInstantiationException if the bean cannot be instantiated
  * @see Constructor#newInstance
  */
 public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
  Assert.notNull(ctor, "Constructor must not be null");
  try {
   ReflectionUtils.makeAccessible(ctor);
   if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
    return KotlinDelegate.instantiateClass(ctor, args);
   }
   else {
    Class<?>[] parameterTypes = ctor.getParameterTypes();
    Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
    Object[] argsWithDefaultValues = new Object[args.length];
    for (int i = 0 ; i < args.length; i++) {
     if (args[i] == null) {
      Class<?> parameterType = parameterTypes[i];
      argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
     }
     else {
      argsWithDefaultValues[i] = args[i];
     }
    }
    return ctor.newInstance(argsWithDefaultValues);
   }
  }
  catch (InstantiationException ex) {
   throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
  }
  catch (IllegalAccessException ex) {
   throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
  }
  catch (IllegalArgumentException ex) {
   throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
  }
  catch (InvocationTargetException ex) {
   throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
  }
 }

方法12:finishRefresh() => 完成刷新

 /**
  * Finish the refresh of this context, invoking the LifecycleProcessor's
  * onRefresh() method and publishing the
  * {@link org.springframework.context.event.ContextRefreshedEvent}.
  */
 protected void finishRefresh() {
  // Clear context-level resource caches (such as ASM metadata from scanning).
  // 
  clearResourceCaches();

  // Initialize lifecycle processor for this context.
  initLifecycleProcessor();

  // Propagate refresh to lifecycle processor first.
  getLifecycleProcessor().onRefresh();

  // Publish the final event.
  publishEvent(new ContextRefreshedEvent(this));

  // Participate in LiveBeansView MBean, if active.
  LiveBeansView.registerApplicationContext(this);
 }

方法13:resetCommonCaches() => 缓存重置

 /**
  * Reset Spring's common reflection metadata caches, in particular the
  * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}
  * and {@link CachedIntrospectionResults} caches.
  * @since 4.2
  * @see ReflectionUtils#clearCache()
  * @see AnnotationUtils#clearCache()
  * @see ResolvableType#clearCache()
  * @see CachedIntrospectionResults#clearClassLoader(ClassLoader)
  */
 protected void resetCommonCaches() {
  ReflectionUtils.clearCache();
  AnnotationUtils.clearCache();
  ResolvableType.clearCache();
  CachedIntrospectionResults.clearClassLoader(getClassLoader());
 }

最后回顾整个流程概览图:

1、Intellij IDEA这样 配置注释模板,让你瞬间高出一个逼格!
2、吊炸天的 Docker 图形化工具 Portainer,必须推荐给你!
3、最牛逼的 Java 日志框架,性能无敌,横扫所有对手!
4、把Redis当作队列来用,真的合适吗?
5、惊呆了,Spring Boot居然这么耗内存!你知道吗?
6、全网最全 Java 日志框架适配方案!还有谁不会?
7、Spring中毒太深,离开Spring我居然连最基本的接口都不会写了

点分享

点收藏

点点赞

点在看

浏览 22
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报