Spring启动流程、三级缓存、BeanDefinition讲解

Spring启动流程

创建上下文对象

//创建上下文对象,下边是源码流程
AnnotationConfigApplicationContext annotationConfigApplicationContext =new AnnotationConfigApplicationContext(ImportConfig.class);

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		/**
		 * 调用父类构造方法,获取Bean工厂,默认DefaultListableBeanFactory
		 * 初始化内置的工厂后置处理器,可以用于解析常用注解
		 * 初始化环境信息,类加载器,初始化配置文件解析器
		 *
		 * 五个内置BeanDefinition
		 * BeanFactory.BeanDefinitionMap=>
		 * 0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
		 * 这个BeanDefinition是ConfigurationClassPostProcessor生成的,显示的是key值,value为BeanDefinition。
		 * ConfigurationClassPostProcessor的作用在下边补充
		 * 1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
		 * 2 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
		 * 3 = "org.springframework.context.event.internalEventListenerProcessor"
		 * 4 = "org.springframework.context.event.internalEventListenerFactory"
		 */
		this();
    	//register(componentClasses) 注册ImportConfig的BeanDefinition
    	// BeanFactory.BeanDefinitionMap加一个ImportConfig的BeanDefinition
		register(componentClasses);
    	//刷新阶段
		refresh();
    	//prepareRefresh 准备上下文
    	//obtainFreshBeanFactory 获取Bean工厂
    	//prepareBeanFactory Bean工厂初始化
    	//postProcessBeanFactory 后置处理Bean工厂,空方法,扩展点
    	//invokeBeanFactoryPostProcessors 执行BeanFactory的后置处理器。在这里
    	//扫描@Component那些BeanDefinition
    	//执行@Import的逻辑
    
    	//registerBeanPostProcessors 注册Bean的后置处理器,用于拦截Bean的创建
    	//initMessageSource 初始化消息源
    	//initApplicationEventMulticaster 初始化事件派发器,用来发布事件
    	//onRefresh 用来初始化一些特殊的Bean,目前默认是空方法,未实现
    	//registerListeners 注册监听器
    	//finishBeanFactoryInitialization 初始化所有剩余的单实例Bean(没有使用懒加载的Bean).整个Spring IOC的核心
    	//finishRefresh 发布事件
}

ConfigurationClassPostProcessor 是什么?
我们都知道,spring 容器管理了好多 bean, 方便了我们的开发,当我们用到某个实例的时候,不用一个一个的去 new 一个对象出来,而是直接从 Spring 容器里拿。可是 Spring 怎么把对应的 Class 一个个实例化为 bean 的呢?总体这个流程是分为两步,第一步是扫描出来所有需要由 Spring 容器管理的类并将其注册为 beanDefinition, 比如添加了@Component 注解,或者由@Import 引入的类,都会在第一步被扫描到,进而注册为 beanDefinition。第二步就是根据beanDifiniton 来把 bean 一个个创建出来。ConfigurationClassPostProcessor 就是做第一步的工作的,即扫描所有需要实例化的 bean 定义。

this()方法

调用父类构造方法,获取Bean工厂,默认DefaultListableBeanFactory

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
 //省略其它代码
   public GenericApplicationContext() {
      this.beanFactory = new DefaultListableBeanFactory();
   }
}

注册5个内置BeanDefinition

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		// ConfigurationClassPostProcessor实例会在bean工厂后置处理器调用时处理配置类
    	//通过@ComponentScan注解扫描需要生成BeanDefinition的类
    	//@PropertySource,@Import, @ImportResource,@Bean 注解也会被处理
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

refresh()刷新方法

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			/**
			 * 1.准备上下文的刷新工作,记录bean容器的启动时间,容器活跃状态
			 *    验证系统中一些属性和属性值的设置等.
			 *    使用LinkedHashSet初始化earlyApplicationListeners和earlyApplicationEvents
			 */
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			/**
			 * 2.获取Bean工厂,设置序列化id.
			 * 此处返回的beanFactory的真实类型为:DefaultListableBeanFactory
			 * 即前文上下文对象父类构造器生成的bean工厂
			 *
			 */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			/**
			 * 3.bean工厂的初始化准备工作,设置bean工厂的一些属性
			 * 比如:创建bean工厂时,需要忽略哪些接口,需要注册哪些bean,需要设置哪些Bean的后置处理器等.
			 *
			 * 例如常用的添加bean后置处理器:ApplicationContextAwareBeanPostProcessor, ApplicationListenerDetector
			 *
			 * 此外,注册一些和环境相关的bean单实例bean.
			 */
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				/**
				 * 4.Bean定义加载完毕之后实现,目前方法为空实现,留给开发人员进行自定义扩展。
				 * 	  和BeanFactoryPostProcessor中的方法postProcessBeanFactory相同
				 *
				 * 该方法在Bean定义加载完毕之后,Bean实例化之前会执行
				 * 比如在BeanFactory加载完所有的Bean定义之后,想要修改某个bean的定义信息,可以通过重写这个方法实现.
				 * 比如:在xml中配置了<bean id="user"><property name="name" value="wb"></property></bean>
				 * 如果想在不修改配置文件的情况下修改name的值,可以使用如下的方法:
				 * class MyApplicationContext extends ClassPathXmlApplicationContext{
				 public MyApplicationContext(String s){
				 super(s);
				 }
				 @Override
				 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
				 BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");
				 PropertyValue propertyValue=new PropertyValue("name", "www.so.com");
				 beanDefinition.getPropertyValues().addPropertyValue(propertyValue);
				 }
				 */
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				/**
				 * 5.执行beanFactory的后置处理器
				 *
				 * 调用bean工厂的后置处理器,有两种 BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
                 * BeanDefinitionRegistryPostProcessor优先级大于BeanFactoryPostProcessor
				 * BeanDefinitionRegistryPostProcessor内优先级是 new出来对象 > 实现PriorityOrdered接口对象 > 实现				 * Ordered接口对象> 容器中对象
				 * BeanFactoryPostProcessor 同理
				 *
				 *
				 * 在这里,ConfigurationClassPostProcessor bean工厂的后置处理器将用户自定义的Bean
				 * 扫描为BeanDefinition,加入BeanFactory.beanDefinitionMap
				 * 配置类中的Selector类型的组件和@Component,@ComponentScan中的元数据信息也会在该步骤中进行解析
				 * 还包括执行条件注解@Condition的回调逻辑
				 *
				 *  注册@Import里的类成为BeanDefinition加入BeanFactory.beanDefinitionMap
				 *  ImportBeanDefinitionRegistrar对应的registerBeanDefinitions方法也会在该步骤中调用,给容器中注册自定义的组件.
				 *
				 *  
				 */
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				/**
				 * 6. 注册所有bean的后置处理器,用于拦截Bean的创建
				 * 两类BeanPostProcessor和MergedBeanDefinitionPostProcessor
				 * BeanPostProcessor会被获取实例
				 * BeanPostProcessor也会被排序,
				 * PriorityOrdered->Ordered->普通的
				 * 
				 * BeanPostProcessor优先级大于MergedBeanDefinitionPostProcessor,但是                                     		 * MergedBeanDefinitionPostProcessor的合并bean接口最先调用
				 * BeanPostProcessor内优先级是 new出来对象 > 实现PriorityOrdered接口对象 > 实现Ordered接口对象> 容器				  * 中对象
				 */
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				/**
				 * 7.初始化消息源
				 * 用来做国际化,消息绑定,消息解析等功能
				 * 一般在SpringMVC中会使用到.
				 */
				initMessageSource();

				// Initialize event multicaster for this context.
				/**
				 * 8.初始化事件派发器,用来发布事件
				 * 	如果容器中有类型为ApplicationEventMulticaster的派发器组件,则直接获取使用
				 * 	如果容器中没有,则默认创建一个类型为SimpleApplicationEventMulticaster的派发器并加入容器,供容器派发事件使用
				 */
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				/**
				 * 9.用来初始化一些特殊的Bean,目前默认是空方法,未实现,可以通过继承AbstractApplicationContext类,
				 *   然后覆写该方法进行自定义特殊bean的初始化.
				 *
				 * 比如:AbstractRefreshableWebApplicationContext中onRefresh方法用来初始化主题能力.
				 *
				 * SpringBoot也是在改步骤中启动内嵌Tomcat容器的
				 */
				onRefresh();

				// Check for listener beans and register them.
				/**
				 * 10.注册监听器
				 * 将监听器绑定到广播器上,将监听器对应的beanName绑定到到第8步初始化的事件派发器中,
				 *   如果之前有发布的事件,则直接通过事件派发器将事件派发出去.
				 */
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				/**
				 * 11.初始化所有剩余的单实例Bean(没有使用懒加载的Bean).整个Spring IOC的核心.
				 *
				 * 包括执行@PostConstruct标注的方法.
				 *
				 * 注意:SpringMVC的父子容器创建Bean的过程:
				 *   SpringMVC中,存在着父容器和子容器。当父容器启动之后,会通过该方法将所有的Dao和Service对应的Bean创建出来,保存到beanFactory的单例缓存容器中
				 *   当子容器启动之后,也会通过该方法将所有的Controller,viewResolver,HandlerMapping对应的Bean创建出来,然后放入到beanFactory的单例缓存容器中.
				 */
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				/**
				 *  12.发布事件。例如容器中的刷新事件:ContextRefreshedEvent就是在这一步中发布. SpringCloud在该步骤中会启动web服务
				 *
				 */
				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();
			}
		}
	}

BeanDefinition讲解和创建bean流程

BeanDefinition讲解

​ ​ ​ ​ BeanDefinition 是用来描述 Bean 的,里面存放着关于 Bean 的一系列信息,比如 Bean 的作用域,Bean 所对应的 class, 是否懒加载,是否 Primary 等等。有了它 Spring 容器就掌握了实例化 bean 所需要的一些重要信息,Spring 才可以对其进行实例化。
​ ​ ​ ​ 这里你可能会想,Spring 实例化一个对象怎么这么复杂,我们自己实例化的时候,不就拿到对应的类,new 一下不就完事了么,哪里需要什么 beanDefinition, 而 Spring 容器的作用不就是替我们保存一些实例,我们需要的时候向他索取,那么它也 new 一堆对象保存着不就行了么。
​ ​ ​ ​ 其实问题也就出在 new 一堆对象这件事上,Spring容器管理着很多很多对象,比如你写一个@Component 注解,它就要实例化一个对象保存着,那么当你启动 Spring 容器的时候面对那么多要实例化的对象,它要先去实例化谁呢?比如说,你可能用了 @DepentOn 注解,就意味着一个 bean 是要优先于另外一个 bean 被实例化出来的。如果你用了@Lazy 注解,那么 Spring 容器启动的时候并不会实例化这个bean,而是等你真正问 Spring 容器要这个实例的时候,它才会给你创建一个 bean 出来。此外有的 bean是多例,而有的是单例,这样的话是不是发现只用一个类来 new 一个对象是不是根本满足不了上面的需求了。所以就有了 beanDefinition 的概念。它描述了 bean 的各种信息。使得 spring 容器能够很好的实例化管理 bean。

代码举例
实体类代码

public class User {
    private String name;
    private String sex;
 
    public User() {
 
    }
 
    public User(String name, String sex) {
        this.name = name;
        this.sex = sex;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getSex() {
        return sex;
    }
 
    public void setSex(String sex) {
        this.sex = sex;
    }
 
    @Override
    public String toString() {
        return "User{" +
            "name='" + name + '\'' +
            ", sex='" + sex + '\'' +
            '}';
    }
}
       

测试代码:

public class TestDefinitionMain {
    public static void main(String[] args) {
        //实例化一个容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //实例化一个 beanDefinition
        RootBeanDefinition beanDefinition = new RootBeanDefinition(User.class);
        //注册 beanDefinition
        beanFactory.registerBeanDefinition("user1", beanDefinition);
        //从容器里获取 bean 实例,如果没有的话,会去创建一个 bean 并返回
        User user1 = beanFactory.getBean("user1", User.class);
        System.out.println(user1);
 
        //也可以通过操作 beanDefinition, 传入构造方法的参数,进而影响实例化 bean
        //实例化一个 beanDefinition
        RootBeanDefinition beanDefinition2 = new RootBeanDefinition(User.class);
        //添加构造方法的参数
        ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
        constructorArgumentValues.addIndexedArgumentValue(0, "cison");
        constructorArgumentValues.addIndexedArgumentValue(1, "男");
        beanDefinition2.setConstructorArgumentValues(constructorArgumentValues);
        //注册bean定义
        beanFactory.registerBeanDefinition("user2", beanDefinition2);
        User user2 = beanFactory.getBean("user2", User.class);
        System.out.println(user2);
    }
}

运行结果如下,至此我们已经通过注册 bean 定义,进而在容器中实例化一个 bean:

User{name='null', sex='null'}
User{name='cison', sex='男'}

注册BeanDefinition和创建bean源码剖析

​ 从上面实例代码可以看到,主要的两个方法为 beanFactory.registerBeanDefinition() 注册BeanDefinition和beanFactory.getBean()创建bean,分别剖析一下这两个方法到底做了什么。

注册BeanDefinition

点进去 beanFactory.registerBeanDefinition() ,源码如下:

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
 
		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        //我们所用的是 RootBeanDefinition, 所以 if 条件这里不用考虑
		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
        
        //判断是否已经注册了该 bean 的 bean定义,很明显我们第一次注册,这里获取为空,故这个 if 条件也跳过
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
            //这里判断bean是否已经开始创建,很明显这里第一次注册bean定义,是没有的进行创建的
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
                //最终逻辑会走到这里
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
 
		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
		else if (isConfigurationFrozen()) {
			clearByTypeCache();
		}
	}

从上面可以看到,代码最终会走到如下代码段,由此可知,注册bean定义,其实就是在将bean定义的信息,保存到 bean 容器的两个局部变量里,其中 beanDefinitionMap 保存bean名称和bean定义的映射关系,beanDefinitionNames 保存所有bean的名称。

this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);

创建bean

beanFactory.getBean()

这是创建 bean 的方法,点进去可以看到如下代码

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    return doGetBean(name, requiredType, null, false);
}

可以看到真正创建 bean 的方法为 doGetBean(),继续往下走

    protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
        throws BeansException {
 
        //该方法判断该 bean 是否有别名,如果有的话就转换一下名称
        String beanName = transformedBeanName(name);
        Object bean;
 
        // Eagerly check singleton cache for manually registered singletons.
        //该方法从三级缓存里尝试获取 bean,因为当前是第一次创建,故返回值为 null, 故下面 if 逻辑不会进去
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                // 与下面的 prototype 的 bean 不同,如果创建单例 bean 的时候发现该 bean 正在被创建,这说明出现了循环依赖,但是并没有立刻抛出异常,而是会将当前还没有完全创建好的 bean 返回(当然这也可能会出现问题,后面文章再分析)
                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.
            // Spring 只解决了单例 bean 的循环依赖问题,如果是 prototype 类型的 bean 出现了循环依赖则会跑出异常
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
 
            // Check if bean definition exists in this factory.
            // 如果当前容器没有获取到bean定义,则会尝试从父容器中获取
            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);
                }
            }
 
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }
 
            try {
                // 如果当前容器和父容器中都有改bean定义,就会将二者合并一下
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);
 
                // Guarantee initialization of beans that the current bean depends on.
                // 如果配置了 @Dependon, 那么就会创建它所依赖的 bean
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        // 如果互相dependson, 就会抛出异常,注意这里不是循环依赖,而是二者都标注了 @DependOn 对方的注解,都想让对方先创建出来
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            // 创建当前 bean 依赖的 bean, 也是调用 getBean 方法
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }
 
                // Create bean instance.
                if (mbd.isSingleton()) {
                    // 创建单例 bean, 其中 getSingleton 方法是创建 bean 之前进行一写预备工作,createBean 是一个回调方法,该方法是真正实例化 bean 的地方
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                           //.. 省略部分处理异常代码
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
 
        // ....省略部分代码
        return (T) bean;
    }

通过以上代码及注释,我们会走到如下代码这一行,这里是获取 bean 定义的,那么怎么获取呢,由上面注册bean定义的流程可以猜测,因为注册bean定义的时候,其实是把 bean 定义放入到了容器的一个局部变量 beanDefinitionMap 里,那么当要获取 bean 定义的时候,最终应该也是是从beanDefinitionMap 中来根据名称获取bean定义的。下面我们就继续跟进下面这行代码,来验证我们的猜想。

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
点进去 getMergedLocalBeanDefinition 可以看到

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
    // Quick check on the concurrent map first, with minimal locking.
    //这一行是获取合并之后的 bean 定义的,因为我们目前没有涉及与父 bean 的合并,故获取到 null
	RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
	if (mbd != null && !mbd.stale) {
		return mbd;
	}
    //最终会走到这一行
	return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

我们留意到最后一行调用方法的第二个参数,是调用另外一个方法的返回值,我们跟进getBeanDefinition(beanName)

public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
    //果然是你!!!
	BeanDefinition bd = this.beanDefinitionMap.get(beanName);
	if (bd == null) {
		if (logger.isTraceEnabled()) {
			logger.trace("No bean named '" + beanName + "' found in " + this);
		}
		throw new NoSuchBeanDefinitionException(beanName);
	}
	return bd;
}

我们可以看到,最终果然是从 beanDefinitionMap 中获取到的 bean 定义。至于getMergedBeanDefinition 方法,它是用来合并父亲和孩子之间的bean定义的,目前我们不需要,故暂不讨论。接着我们返回创建 bean 的主流程中去。

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
这里就得到了 bean 定义,然后接下来的核心代码如下

//首先从bean定义中获取 dependOn 信息, 在声明bean的时候可以使用 @Dependon 注解指定在哪些bean创建之后再创建当前bean,我们样例中没有配置,故这里获取到 null,
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
    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()) {
    //单例bean的创建流程
    sharedInstance = getSingleton(beanName, () -> {
	    try {
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
            destroySingleton(beanName);
			throw ex;
						}
	    });
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

由上也可以看到 beanDefinition 的作用,可以看到它存储了 bean 的 dependOn 信息和作用域信息,用于控制创建 bean 的流程, 接下来就是真正创建 bean 的流程了,getSingleton 传入bean名称和一个钩子函数,在 getSingleton 方法里有这个一行代码 singletonObject = singletonFactory.getObject(); 这就是调用钩子函数来创建bean实例,所以我们这里直接跟进钩子函数的 createBean(beanName, mbd, args) 方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
 
		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;
 
		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
 
		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}
 
		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            //这里是常识创建代理对象,因为我们样例没有配置代理,故这里获取到 null
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}
 
		try {
            //创建普通 bean 的方法
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

上面这段代码有两段逻辑,先尝试创建代理对象,如果该 bean 需要被代理,那么就会创建代理对象成功并返回,否则就会进入下面创建普通 bean 的流程 doCreateBean(beanName, mbdToUse, args)

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
 
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
            //在这里通过构造器反射获取到对象实例
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		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 {
            //属性赋值,依赖注入
			populateBean(beanName, mbd, instanceWrapper);
            //初始化bean
			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 " +
								"'getBeanNamesForType' 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;
	}

该方法里获得实例对象是这一行代码,它底层比较复杂,但是原理就是获取实例类的构造器,通过反射生成一个对象。至此,我们通过getBean()方法就得到了一个实例 bean,后续会有一些初始化,实例化,增强的逻辑,这里暂时就不展开了。

instanceWrapper = createBeanInstance(beanName, mbd, args);

模拟构造器反射生成对象实例

public class TestDefinitionMain {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //实例化一个容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //实例化一个 beanDefinition
        RootBeanDefinition beanDefinition = new RootBeanDefinition(User.class);
        //注册 beanDefinition
        beanFactory.registerBeanDefinition("user1", beanDefinition);
        //从容器里获取 bean 实例,如果没有的话,会去创建一个 bean 并返回
        User user1 = beanFactory.getBean("user1", User.class);
        System.out.println(user1);
 
        //也可以通过操作 beanDefinition, 传入构造方法的参数,进而影响实例化 bean
        //实例化一个 beanDefinition
        RootBeanDefinition beanDefinition2 = new RootBeanDefinition(User.class);
        //添加构造方法的参数
        ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
        constructorArgumentValues.addIndexedArgumentValue(0, "cison");
        constructorArgumentValues.addIndexedArgumentValue(1, "男");
        beanDefinition2.setConstructorArgumentValues(constructorArgumentValues);
        //注册bean定义
        beanFactory.registerBeanDefinition("user2", beanDefinition2);
        User user2 = beanFactory.getBean("user2", User.class);
        System.out.println(user2);
 
        //构造器反射获取实例 candidate.newInstance();
        Constructor<?>[] candidates = User.class.getDeclaredConstructors();
        for (Constructor candidate : candidates) {
            int parameterCount = candidate.getParameterCount();
            if (parameterCount == 0) {
                //通过反射实例化对象
                User user3 = (User) candidate.newInstance();
                System.out.println("user3:" + user3);
            } else {
                //模拟解析参数
                ConstructorArgumentValues paramValues = beanDefinition2.getConstructorArgumentValues();
                Map<Integer, ConstructorArgumentValues.ValueHolder> indexedArgumentValues = paramValues.getIndexedArgumentValues();
                Object[] args0 = new Object[2];
                args0[0] = indexedArgumentValues.get(0).getValue();
                args0[1] = indexedArgumentValues.get(1).getValue();
                //通过反射实例化对象
                User user4 = (User) candidate.newInstance(args0);
                System.out.println("user4:" + user4);
            }
        }
    }
}
      

执行结果

User{name='null', sex='null'}
User{name='cison', sex='男'}
user3:User{name='null', sex='null'}
user4:User{name='cison', sex='男'}

bean创建流程图

在这里插入图片描述

三级缓存如何解决循环依赖

什么是三级缓存

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
	// 一级缓存。value装的是成品bean
	/** Cache of singleton objects: bean name to bean instance. */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
 
	// 三级缓存。value装的是函数式接口的具体实例,核心就是里面的方法。因此可以简单地理解为装的就是一个lambda表达式
	/** Cache of singleton factories: bean name to ObjectFactory. */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
 
	// 二级缓存。value装的是半成品bean
	/** Cache of early singleton objects: bean name to bean instance. */
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
}

执行流程简单描述

1.Bean实例化前会先查询缓存,判断Bean是否已经存在

2.Bean属性赋值前会先向三级缓存中放入一个lambda表达式,该表达式执行则会生成一个半成品Bean放入二级缓存

3.Bean初始化完成后将完整的Bean放入一级缓存,同时清空二、三级缓存

Bean实例化前

AbstractBeanFactory.doGetBean

Bean实例化前会从缓存里面获取Bean,防止重复实例化

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object beanInstance;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		// …… 省略其它代码

DefaultSingletonBeanRegistry.getSingleton(String beanName, boolean allowEarlyReference)

我们看看这个获取的方法逻辑:

从一级缓存获取,获取到了,则返回
从二级缓存获取,获取到了,则返回
从三级缓存获取,获取到了,则执行三级缓存中的lambda表达式,将结果放入二级缓存,清除三级缓存

public Object getSingleton(String beanName) {
    return this.getSingleton(beanName, true);
}

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 从一级缓存中获取Bean 获取到了则返回 没获取到继续
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
        // 从二级缓存中获取Bean  获取到了则返回 没获取到则继续
        singletonObject = this.earlySingletonObjects.get(beanName);
        if (singletonObject == null && allowEarlyReference) {
            // 加一把锁防止 线程安全 双重获取校验
            synchronized(this.singletonObjects) {
                // 从一级缓存中获取Bean 获取到了则返回 没获取到继续
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    // 从二级缓存中获取Bean  获取到了则返回 没获取到则继续
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    if (singletonObject == null) {
                        // 从三级缓存中获取 没获取到则返回
                        ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            // 获取到了 执行三级缓存中的lambda表达式
                            singletonObject = singletonFactory.getObject();
                            // 并将结果放入二级缓存
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            // 从三级缓存中移除
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
        }
    }

    return singletonObject;
}


属性赋值/依赖注入前

AbstractAutowireCapableBeanFactory.doCreateBean

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");
			}
            // 这里就是将一个lambda表达式放入了三级缓存,我们需要去看一下这个表达式是干什么的
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

DefaultSingletonBeanRegistry.addSingletonFactory

这里就是将一个lambda表达式放入了三级缓存,我们需要去看一下这个表达式是干什么的


protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    synchronized(this.singletonObjects) {
        // 一级缓存中不存在的话 
        if (!this.singletonObjects.containsKey(beanName)) {
            // 将lambda表达式放入三级缓存
            this.singletonFactories.put(beanName, singletonFactory);
            // 清除二级缓存 
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}

AbstractAutowireCapableBeanFactory.getEarlyBeanReference

该方法说白了就是会判断该Bean是否需要被动态代理,两种返回结果:

不需要代理,返回未属性注入、未初始化的半成品Bean
需要代理,返回未属性注入、未初始化的半成品Bean的代理对象

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
        Iterator var5 = this.getBeanPostProcessors().iterator();
        // 遍历后置处理器
        while(var5.hasNext()) {
            BeanPostProcessor bp = (BeanPostProcessor)var5.next();
            // 找到实现SmartInstantiationAwareBeanPostProcessor接口的
            // 该接口getEarlyBeanReference方法什么时候会执行?
            // AOP动态代理的时候 该方法执行就是判断该Bean是否需要被代理
            // 需要代理则会创建代理对象返回
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
                exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
            }
        }
    }
    // 这个Object有两种情况,一是实例化后的半成品Bean,二是半成品Bean动态代理后的代理对象
    return exposedObject;
}
注意:这里只是把lambda表达式放入了三级缓存,如果不从三级缓存中获取,这个表达式是不执行的,一旦执行了,就会把半成品Bean或者半成品Bean的代理对象放入二级缓存中了

初始化后

AbstractBeanFactory.doGetBean

这里注意啊,这个getSingleton方法传参传了个lambda表达式,会在getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法中调用这个lambda表达式,这个表达式内部就是Bean的实例化过程

// 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;
						}
					});
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

DefaultSingletonBeanRegistry.getSingleton(beanName, singletonFactory)

这个方法与上面那个不一样,重载了,我们看一看这个方法

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        synchronized(this.singletonObjects) {
        // 第一次进来这里获取肯定为null
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
           // 省略................
            try {
                // 注意啊,这个就是执行外面那个传参的lambda表达式
                // 所以这里才会跳到createBean方法那里去执行
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            } 
            // 省略................
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                this.afterSingletonCreation(beanName);
            }
            // 到了这说明Bean创建完了
            if (newSingleton) {
                // 这里就会把Bean放入一级缓存中了 同时清除二、三级缓存
                this.addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

DefaultSingletonBeanRegistry.addSingleton

protected void addSingleton(String beanName, Object singletonObject) {
  synchronized(this.singletonObjects) {
     // 放入一级缓存  
      this.singletonObjects.put(beanName, singletonObject);
      // 清除二、三级缓存
      this.singletonFactories.remove(beanName);
      this.earlySingletonObjects.remove(beanName);
      this.registeredSingletons.add(beanName);
  }
}

总结
整个过程就三个地方跟缓存有关,我们假设现在要实例化A这个Bean,看看缓存是怎么变化的:

实例化前,获取缓存判断(三个缓存中肯定没有A,获取为null,进入实例化流程)
实例化完成,属性注入前(往三级缓存中放入了一个lambda表达式,一、二级为null)
初始化完成(将A这个Bean放入一级缓存,清除二、三级缓存)
以上则是单个Bean生成过程中缓存的变化!!

流程图

以A注入B,B注入A为例:
流程为doCreateBean(A) ->addSingletonFactory(A)->populateBean(A) -> doCreateBean(B) ->addSingletonFactory(B) -> populateBean(B) ->getSingleton(A) -> B添加到IOC容器中->getSingleton(B) -> A添加的IOC容器中
addSingletonFactory:把lambda表达式放入了第三级缓存
A属性注入前就把lambda表达式放入了第三级缓存,所以B再注入A的时候会从第三级缓存中找到A的lambda表达式并执行,然后将半成品Bean放入第二级缓存,所以此时B注入的只是半成品的A对象,B创建完成后返回给A注入,A继续初始化,完成创建。

注意: B注入的半成品对象是A的代理对象,持有A的引用,所以之后A初始化完成后,B这个注入的代理对象,随着A对象的属性填充和初始化就变成了完整的A的代理对象,最终A初始化完成,会把A的代理对象的引用赋值给A暴露出去,A也就完成了创建

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);
						}
					}
             // ……………………其它代码省略

在这里插入图片描述

为什么使用三级缓存,二级行不行

A是单例的,也就是要保证,在Spring中,使用到该bean的地方,都是同一个bean才行。但是每次执行singletonFactory.getObject()都会产生新的代理对象。假设只有一级和三级缓存,每次从三级缓存中获取代理对象,都会产生新的代理对象,忽略性能不说,是不符合单例原则的。

所以这里我们要借助二级缓存来解决这个问题,将singleFactory.getObject()产生的对象放到二级缓存中去,后面直接从二级缓存中拿,保证始终只有一个代理对象。

BeanFactory和FactoryBean的区别

**共同点:**都是接口

区别:

BeanFactory 以Factory结尾,表示它是一个工厂类,用于管理Bean的一个工厂。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。该接口是IoC容器的顶级接口,是IoC容器的最基础实现,也是访问Spring容器的根接口,负责对bean的创建,访问等工作
对FactoryBean而言,以Bean结尾,说明这是一个交给容器去管理的bean。这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。

源码解析

public interface FactoryBean<T> {

	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

	@Nullable
	T getObject() throws Exception;

	@Nullable
	Class<?> getObjectType();

	default boolean isSingleton() {
		return true;
	}

}

AbstractFactory.doGetBean方法中,最后getObjectForBeanInstance方法都会对实例化的bean,进行判断是否为FactoryBean类型,如果是调用getObject获取修饰对象

protected <T> T doGetBean(
            String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
            throws BeansException {
        // 其余代码省略
    	// 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;
                }
            });
            beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }
    }

进入getObjectForBeanInstance方法

protected Object getObjectForBeanInstance(
      Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

   // Don't let calling code try to dereference the factory if the bean isn't a factory.
   //如果name不为null且以&开头进入if
   if (BeanFactoryUtils.isFactoryDereference(name)) {
      if (beanInstance instanceof NullBean) {
         return beanInstance;
      }
      if (!(beanInstance instanceof FactoryBean)) {
         throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
      }
      if (mbd != null) {
         mbd.isFactoryBean = true;
      }
       //带&符号直接返回FactoryBean对象,不带执行下边getObjectFromFactoryBean方法返回真正实例
      return beanInstance;
   }

   // Now we have the bean instance, which may be a normal bean or a FactoryBean.
   // If it's a FactoryBean, we use it to create a bean instance, unless the
   // caller actually wants a reference to the factory.
   //不是FactoryBean对象直接返回
   if (!(beanInstance instanceof FactoryBean)) {
      return beanInstance;
   }

   Object object = null;
   if (mbd != null) {
      mbd.isFactoryBean = true;
   }
   else {
      object = getCachedObjectForFactoryBean(beanName);
   }
   if (object == null) {
      // Return bean instance from factory.
      FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
      // Caches object obtained from FactoryBean if it is a singleton.
      if (mbd == null && containsBeanDefinition(beanName)) {
         mbd = getMergedLocalBeanDefinition(beanName);
      }
      boolean synthetic = (mbd != null && mbd.isSynthetic());
      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
   }
   return object;
}

进入FactoryBeanRegistrySupport.getObjectFromFactoryBean方法

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					object = doGetObjectFromFactoryBean(factory, beanName);
					// Only post-process and store if not put there already during getObject() call above
					// (e.g. because of circular reference processing triggered by custom getBean calls)
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						if (shouldPostProcess) {
							if (isSingletonCurrentlyInCreation(beanName)) {
								// Temporarily return non-post-processed object, not storing it yet..
								return object;
							}
							beforeSingletonCreation(beanName);
							try {
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
							finally {
								afterSingletonCreation(beanName);
							}
						}
						if (containsSingleton(beanName)) {
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		else {
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (shouldPostProcess) {
				try {
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}

再进入doGetObjectFromFactoryBean

private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
   Object object;
   try {
      if (System.getSecurityManager() != null) {
         AccessControlContext acc = getAccessControlContext();
         try {
            object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
          //重点在这,调用getObject方法获取factoryBean封装的对象
         object = factory.getObject();
      }
   }
   catch (FactoryBeanNotInitializedException ex) {
      throw new BeanCurrentlyInCreationException(beanName, ex.toString());
   }
   catch (Throwable ex) {
      throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
   }

   // Do not accept a null value for a FactoryBean that's not fully
   // initialized yet: Many FactoryBeans just return null then.
   if (object == null) {
      if (isSingletonCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(
               beanName, "FactoryBean which is currently in creation returned null from getObject");
      }
      object = new NullBean();
   }
   return object;
}
  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值