# 1. Bean的实例化概述 前一篇分析了BeanDefinition的封装过程,最终将beanName与BeanDefinition以一对一映射关系放到beanDefinitionMap容器中,这一篇重点分析如何利用bean的定义信息BeanDefinition实例化bean。 Spring学习笔记地址:[Spring核心170多页学习笔记](https://mp.weixin.qq.com/s/L9wgm0LaSV0SVQqjQPHyaA) # 2. 流程概览 其实bean的实例化过程比较复杂,中间细节很多,为了抓住重点,先将核心流程梳理出来,主要包含以下几个流程:  step1: 通过反射创建实例; step2:给实例属性赋初始值; step3:如果Bean类实现BeanNameAware接口,则将通过传递Bean的名称来调用setBeanName()方法;如果Bean类实现BeanClassLoaderAware接口,则将通过传递加载此Bean的ClassLoader对象的实例来调用setBeanClassLoader()方法;如果Bean类实现BeanFactoryAware接口,则将通过传递BeanFactory对象的实例来调用setBeanFactory()方法; step4: 如果有类实现BeanPostProcessors接口,则将在初始化之前调用postProcessBeforeInitialization()方法; step5:如果Bean类实现了InitializingBean接口,将调用afterPropertiesSet()方法,如果配置文件中的Bean定义包含init-method属性,则该属性的值将解析为Bean类中的方法名称,并将调用该方法; step6: 如果有类实现BeanPostProcessors接口,则将在初始化之后调用postProcessAfterInitialization()方法; step7:如果Bean类实现DisposableBean接口,则当Application不再需要Bean引用时,将调用destroy()方法;如果配置文件中的Bean定义包含destroy-method属性,那么将调用Bean类中的相应方法定义。 # 3. 源码分析 进入AbstractApplicationContext中的fresh()方法,找到finishBeanFactoryInitialization(beanFactory)方法,该类是bean的实例化的入口,具体的实例化由preInstantiateSingletons()方法触发,见如下代码: ```javascript 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. //xml解析时,把所有beanName都缓存到beanDefinitionNames了 List
beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { //把父BeanDefinition里面的属性拿到子BeanDefinition中 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //如果不是抽象的,单例的,非懒加载的就实例化 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判断bean是否实现了FactoryBean接口 if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean factory = (FactoryBean) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction
) ((SmartFactoryBean) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { // 实例化过程 getBean(beanName); } } } ``` 上述代码主要看getBean方法,随后进入doGetBean方法: ```javascript protected
T doGetBean( String name, @Nullable Class
requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object bean; // 从缓存中获取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); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. 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 // 创建bean实例 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); } ... } ``` 由上述代码可知,先从缓存中获取bean,如果没有,则创建bean,最重要的方法就是getSingleton,该方法第二个参数是个函数式接口,进入getSingleton方法,当调用singletonObject = singletonFactory.getObject()时,会触发函数式接口中的createBean方法,随后一路进入doCreateBean,这个方法里面完成了所有实例化所需的步骤: ```javascript protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. // 真正开始创建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
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. // 有必要时,注册bean的销毁 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } ``` 从上述源码中看出bean的实例化主要分为以下三步: step1:bean的创建; step2:给bean的属性赋值; step3:bean的初始化; 接着得到exposedObject这个已经完全实例化后的bean返回,其中当有必要时,注册bean的销毁,后面再详细看,先抓住主要流程。其中step3也是比较重要的方法,进入该方法: ```javascript protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 激活aware接口 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 初始化前处理的beanPostProcessor wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 激活 init-method方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 初始化后处理的beanPostProcessor wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } ``` 从上面源码可知,梳理出主要的四个步骤: step1:激活aware接口,完成aware接口的相关操作; step2:初始化前处理的beanPostProcessor; step3:完成init-method方法; step4:初始化后处理的beanPostProcessor; BeanPostProcessor作用是对初始化后的bean进行增强处理,在该阶段 BeanPostProcessor 会处理当前容器内所有符合条件的实例化后的 bean 对象。它主要是对 Spring 容器提供的 bean 实例对象进行有效的扩展,允许Spring在初始化 bean 阶段对其进行定制化修改,如处理标记接口或者为其提供代理实现。 # 4. 演示 定义一个MyBeanPostProcessor实现BeanPostProcessor接口 ```javascript public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("post Process Before Initialization 被调用..."); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("post Process after Initialization 被调用..."); return bean; } } ``` 定义一个LifeCycleBean类,实现如下接口: ```javascript public class LifeCycleBean implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware, InitializingBean, DisposableBean { private String property; public String getProperty() { return property; } public void setProperty(String property) { System.out.println("属性注入...."); this.property = property; } public LifeCycleBean(){ System.out.println("构造函数调用..."); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("BeanClassLoaderAware 被调用..."); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryAware 被调用..."); } @Override public void setBeanName(String name) { System.out.println("BeanNameAware 被调用..."); } @Override public void destroy() throws Exception { System.out.println("DisposableBean destroy 被调用..."); } @Override public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean afterPropertiesSet 被调用..."); } public void initMethod(){ System.out.println("init-method 被调用..."); } public void destroyMethod(){ System.out.println("destroy-method 被调用..."); } public void display(){ System.out.println("方法调用..."); } } ``` 指定配置文件spring.xml,配置init-method与destroy-method方法 ```javascript
``` 测试类如下: ```javascript @RunWith(SpringJUnit4Cla***unner.class) @ContextConfiguration(locations = {"classpath:spring.xml"}) public class TestSpring { @Test public void testLifeCycleBean() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); } ``` 执行结果: ```javascript 构造函数调用... 属性注入.... BeanNameAware 被调用... BeanClassLoaderAware 被调用... BeanFactoryAware 被调用... post Process Before Initialization 被调用... InitializingBean afterPropertiesSet 被调用... init-method 被调用... post Process after Initialization 被调用... DisposableBean destroy 被调用... destroy-method 被调用... ``` # 4. 总结 本篇从一个初学者的角度概览了bean的整个生命周期,并描述了其中的主要流程,阅读源码的初始阶段,优先抓住主要流程,别陷入细节,并通过跑案例、写注解、画流程图等方式加深理解,后续将继续分析bean实例化中的核心流程、设计思想等,需要Spring源码学习笔记+知识点总结思维导图+Spring相关面试真题可以关注工中号:[麒麟改bug](https://mp.weixin.qq.com/s/sKHy0OJx7pITFJ33QR7XAg) 获取。
相关文章
,DL依赖查找(Dependency Lookup)等功能。
Spring 是一个IOC容器框架,拥有DI依赖注入(Dependency Injection),DL依赖查找(Dependency Lookup)等功能。
题目: 给定一个非空字符串 s 和一个包含非空单词列表的 字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的 单词。
单词必须按照字母顺序,通过相邻的 单元格内的 字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的 单元格。同一个单...
题目:给定一个经过编码的 字符串,返回它解码后的 字符串。编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
前言在面试 的 时候,对应Spring 的 内容是必面的 知识点之一,Spring 的 整个体系还是比较庞大的 ,对于其深度和广度的 深入了解也是高级开发必须掌握的 知识点,Spring 的 源码 架构及实现逻辑也是架构师必须了解的 内容
LifeCycleBeanpackage main.com.lee.d_lifecycle; public class LifeCycleBean { public LifeCycleBean() { System.out.println("LifeCycleBean 构造了..."); } public void setUp() { ...
引言“请你描述下 Spring Bean 的 生命周期 ?”,这是面试官 考察 Spring 的 常用问题,可见是 Spring 中很重要的 知识点。
继续 Spring 复盘,今天看了下 Spring 的 Bean 生命周期 。
Springboot启动原理解析 **前言** 这其实是一道面试 题,是...
面试官 :你好,聊一聊java中线程的 生命周期 ?
HarmonyOS(鸿蒙)技术社区是由51CTO和华为共同打造的综合性开发和应用技术社区。作为华为的官方战略合作伙伴,51CTO将多年的社区运营经验与华为的技术赋能相结合,为开发者提供高质量有深度的HarmonyOS(鸿蒙)学习交流平台。
大数据时代的微服务之路
共18章 纯洁微笑
¥51.00 715人订阅
自动化运维开发新概念
共20章 抚琴煮酒
¥51.00 575人订阅