spring bean加载过程_Spring如何加载「IOC容器」以及「装载Bean」源码解读

SpringBoot应用开发已经非常普遍,的确,SpringBoot给我们的开发带来了很多便利,但其实,SpringBoot并没有增加什么新特性,只不过是在Spring注解的基础上做了升级版混合使用。SpringBoot的精髓就是自动装配(@EnableAutoConfiguration),我们不需要像以前使用Maven搭建项目时,引入过多的依赖包,同时还需要处理各种包冲突问题,简直是烦的要死,现在只需依赖SpringBoot核心包就能完成简单的应用开发了,所以了解Spring核心原理就非常重要了,下面我们开始从源码角度分析Spring底层原理。

25ec1499bf2b4415bbd2938dfe9c48e7

下面我们首先定义一个实体类和配置类

/** * @Description: Dog实体类 * @Auther: Java思享汇 */@Data@ToStringpublic class Dog  {    private String name;    private Integer age;    public Dog(){        System.out.println("------>构造函数调用");    }    public void init(){        System.out.println("------>init函数调用");    }}
/** * @Description: Configuration配置类 * @Auther: Java思享汇 */@ComponentScan("com.study.spring")@Configurationpublic class DogConfiguration {    public Dog dog(){        return new Dog();    }}

接下来定一个测试类

/** * @Description: 测试类 * @Auther: Java思享汇 */public class Test {    @org.junit.Test    public void test(){        AnnotationConfigApplicationContext ac =new AnnotationConfigApplicationContext(DogConfiguration.class);        Dog dog = (Dog) ac.getBean("dog");        System.out.println(dog);    }}

我们就从AnnotationConfigApplicationContext这个类开始,探究下Spring的IOC容器是如何装载Bean的,源码如下:

public AnnotationConfigApplicationContext(Class>... annotatedClasses) {this();register(annotatedClasses);//重点在下面这个方法,创建刷新容器refresh();}

然后,我们继续向下跟踪这个refresh()方法,这个方法在抽象类AbstractApplicationContext下

@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1、刷新前的预处理prepareRefresh();// 2、获取BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 3、BeanFactory的预准备工作(BeanFactory进行一些设置)prepareBeanFactory(beanFactory);try {// 4、BeanFactory准备工作完成后进行的后置处理工作postProcessBeanFactory(beanFactory);// 5、执行BeanFactoryPostProcessor的方法invokeBeanFactoryPostProcessors(beanFactory);// 6、注册BeanPostProcessor(Bean的后置处理器),不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的registerBeanPostProcessors(beanFactory);// 7、初始化MessageSource组件(做国际化功能;消息绑定,消息解析)initMessageSource();// 8、初始化事件派发器;initApplicationEventMulticaster();// 9、留给子容器(子类),空方法onRefresh();// 10、给容器中将所有项目里面的ApplicationListener注册进来registerListeners();// 11、重点在这,初始化所有剩下的单实例bean(自定义的单例bean)finishBeanFactoryInitialization(beanFactory);// 12、完成BeanFactory的初始化创建工作;IOC容器就创建完成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();}}}

通过以上步骤,我们发现Spring的IOC容器主要完成了以下操作:

1⃣️、Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息;

  1. xml注册bean;
  2. 注解注册Bean;@Service、@Component、@Bean

2⃣️、Spring容器会合适的时机创建这些Bean

  1. 用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
  2. 统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();

3⃣️、后置处理器;BeanPostProcessor

  1. 每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;AutowiredAnnotationBeanPostProcessor:处理自动注入AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;xxx…增强的功能注解:AsyncAnnotationBeanPostProcessor…

4⃣️、事件驱动模型;

  1. ApplicationListener;事件监听;
  2. ApplicationEventMulticaster;事件派发:

接下来,我们看下装载我们自己定义的单例bean的过程,主要通过11、finishBeanFactoryInitialization(beanFactory);方法来进行处理。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 1、判断有无ConversionService(bean属性类型转换服务接口),并初始化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));}// 2、如果beanFactory中不包含EmbeddedValueResolver,则向其中添加一个EmbeddedValueResolver  // EmbeddedValueResolver-->解析bean中的占位符和表达式if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(new StringValueResolver() {@Overridepublic String resolveStringValue(String strVal) {return getEnvironment().resolvePlaceholders(strVal);}});}// 3、初始化LoadTimeWeaverAware类型的bean  // LoadTimeWeaverAware-->加载Spring Bean时织入第三方模块,如AspectJString[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// 4、释放临时类加载器beanFactory.setTempClassLoader(null);// 5、冻结缓存的BeanDefinition元数据beanFactory.freezeConfiguration();// 6、重点来了,实例化所有剩余的(非lazy init)单例(包含自定义单例bean)beanFactory.preInstantiateSingletons();}

继续向下跟踪代码,6、beanFactory.preInstantiateSingletons()位于类DefaultListableBeanFactory下,源码如下:

@Overridepublic void preInstantiateSingletons() throws BeansException {if (this.logger.isDebugEnabled()) {this.logger.debug("Pre-instantiating singletons in " + this);}// 1、获取Bean的定义信息List beanNames = new ArrayList(this.beanDefinitionNames);// 2、触发初始化非懒加载单例beansfor (String beanName : beanNames) {// 2.1、根据beanName获取bean的RootBeanDefinitionRootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {    // 2.2、判断为FactoryBean时if (isFactoryBean(beanName)) {final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName);boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {@Overridepublic Boolean run() {return ((SmartFactoryBean>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean>) factory).isEagerInit());}if (isEagerInit) {    // 2.2.1、重点在这,获取创建beangetBean(beanName);}}// 非FactoryBeanelse { getBean(beanName);}}}   // 3、所有Bean都利用getBean创建完成以后,检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated();for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction() {@Overridepublic Object run() {smartSingleton.afterSingletonsInstantiated();return null;}}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}

重点代码在 2.2.1、getBean(beanName);,根据beanName去获取单例bean信息,我们继续跟踪代码,位于类AbstractBeanFactory

@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}protected  T doGetBean(final String name, @Nullable final Class requiredType,@Nullable final Object[] args, boolean typeCheckOnly)throws BeansException {    // 1、转换bean的名称,去掉&前缀,且如果bean有别名的话,优先使用别名    final String beanName = transformedBeanName(name);    Object bean;    // 2、从缓存中获取bean    Object sharedInstance = getSingleton(beanName);    if (sharedInstance != null && args == null) {        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);    }    // 3、如果未能从缓存中获取到bean,则要重新创建bean    else {        // Fail if we're already creating this bean instance: We're assumably within a circular reference.        // 3.1判断指定的原型模式的bean是否当前正在创建(在当前线程内),如果是->则抛出异常(Spring不会解决原型模式bean的循环依赖)        if (isPrototypeCurrentlyInCreation(beanName)) {            throw new BeanCurrentlyInCreationException(beanName);        }        // Check if bean definition exists in this factory.        // 3.2 检测bean definition是否存在beanFactory中        BeanFactory parentBeanFactory = getParentBeanFactory();        // 如果当前BeanFactory中不包含给定beanName的beanDefinition定义,且父beanFactory不为空,则去父beanFactory中再次查找        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {            // 3.3 将name转换为原始beanName            //    因为这里的name已经经过beanName的规范处理,例如:&myBean-->规范-->myBean            //    所以当我们再次去父beanFactory查找时,要将beanName再次转换为原始的beanName,myBean-->回转-->&myBean            String nameToLookup = originalBeanName(name);            // 3.4 下面会递归调用各种getBean的方法重载,从当前bean的父factoryBean中加载bean            if (parentBeanFactory instanceof AbstractBeanFactory) {                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);            }            else if (args != null) {                // 参数不为空,则委托parentBeanFactory使用显式参数调动                return (T) parentBeanFactory.getBean(nameToLookup, args);            }            else if (requiredType != null) {                // 参数为空,则委托parentBeanFactory使用标准的getBean方法获取bean                return parentBeanFactory.getBean(nameToLookup, requiredType);            }            else {                // 否则委托parentBeanFactory使用默认的getBean方法                return (T) parentBeanFactory.getBean(nameToLookup);            }        }        // 3.3 如果当前bean不是用于类型检查,则将该bean标记为已经被创建或者即将被创建        if (!typeCheckOnly) {            markBeanAsCreated(beanName);        }        try {            // 3.4 合并beanDefinition,如果指定的bean是一个子bean的话,则遍历其所有的父bean            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);            // 校验合并的beanDefinition,如果验证失败,则抛出异常            checkMergedBeanDefinition(mbd, beanName, args);            // 3.5 确保初始化当前bean所依赖的bean。            String[] dependsOn = mbd.getDependsOn();            if (dependsOn != null) {                // 循环所有的依赖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 {                        // 实例化依赖的bean                        getBean(dep);                    }                    catch (NoSuchBeanDefinitionException ex) {                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);                    }                }            }            // 3.6 创建单例bean            if (mbd.isSingleton()) {                sharedInstance = getSingleton(beanName, () -> {                    try {                        // 创建bean                        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            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) {            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());        }    }    return (T) bean;}

该过程是为创建当前单例bean的准备工作。其中包括了:对BeanDefinition的检测、如果当前BeanFactory中不包含BeanDefinition则对父BeanFactory的检测、BeanDefinition的合并、依赖bean的初始化等。获取bean时,先从缓存Map中缓存中取,如果缓存中没有则到第3.6步,开始创建单例bean。好的,在以后的文章我们继续介绍Bean的创建过程

不断分享开发过程用到的技术和面试经常被问到的问题,如果您也对IT技术比较感兴趣可以「关注」我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值