Spring源码阅读之bean对象的创建过程

Spring源码阅读之bean对象的创建过程

​ Spring是通过IOC容器来管理对象的,该容器不仅仅只是帮我们创建了对象那么简单,它负责了对象的整个生命周期-创建、装配、销毁。这种方式成为控制反转(组件对象控制权的转移,从程序代码本身转移到了外部容器,容器创建完对象后注入组件中)。

​ Spring的核心的是容器,不过这个容器并不是唯一的,框架本身就提供了很多个容器的实现,大概分为两种类型:

  1. BeanFactory:最简单的容器,只能提供基本的DI(依赖注入)功能。
  2. ApplicationContext(应用上下文):继承自BeanFactory,它能提供更多企业级的服务,例如解析配置文本信息等等,这也是ApplicationContext实例对象最常见的应用场景。

简单说说这两种方式的区别

  1. 原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用
  2. ApplicationContext利用MessageSource进行国际化 并有着事件机制。
  3. ApplicationContext扩展了ResourceLoader(资源加载器)接口,从而可以用来加载多个Resource,而BeanFactory是没有扩展ResourceLoader
  4. 与BeanFactory通常以编程的方式被创建不同的是,ApplicationContext能以声明的方式创建,如使用ContextLoader。当然你也可以使用ApplicationContext的实现之一来以编程的方式创建ApplicationContext实例 。
  5. BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。

ApplicationContext 介绍

​ 如果说BeanFactory是Sping的心脏,那么ApplicationContext就是完整的身躯了。ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在Beanfactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置的方式实现。

ApplicationContext类体系结构:
在这里插入图片描述

在上一篇源码阅读WebContextApplication初始化中说到实际创建的对象为XmlWebApplicationContext,该类继承了AbstractRefreshableWebApplicationContext(上图的左下角),也是ApplicationContext体系。那么该对象读取配置文件后是如何创建bean对象的呢?

大致分为两步:

  1. 实例化BeanDefinition对象(下面分析该对象的作用) 。

  2. 实例化bean对象。

1. 实例化BeanDefinition对象

WebContextApplication初始化说到初始化的步骤是在ContextLoader中完成,创建完XmlWebApplicationContext对象后,通过configureAndRefreshWebApplicationContext()设置配置文件的位置。

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
        String configLocationParam;
        if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
            configLocationParam = sc.getInitParameter("contextId");
            if (configLocationParam != null) {
                wac.setId(configLocationParam);
            } else {
                wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath()));
            }
        }
		//设置ServletContext环境。
        wac.setServletContext(sc);
    	/*读取Servlet对象中的contextConfigLocation.  ServletContext在创建的时候就读取了
    		<context-param>标签,并将该标签中的配置文件的信息通过键值对的形式保存进来了。
    	*/
        configLocationParam = sc.getInitParameter("contextConfigLocation");
        if (configLocationParam != null) {
            //保存配置文件信息的位置。
            wac.setConfigLocation(configLocationParam);
        }
		//刷新环境
        wac.refresh();
    }

​ 配置文件位置设置完成后就需要读取该文件的配置信息,并创建相应的bean对象,这一过程就是在refresh()中完成的。

​ 通过图中的继承关系往上寻找在AbstractApplicationContext中发现·refresh方法,

该方法进行一些初始化操作。

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            // 1.刷新前的预处理,包含设置启动时间、设置状态...
            this.prepareRefresh();
             //实现刷新BeanFactory,将配置文件解析为BeanDefinition并注册到BeanFactory,此时Bean还未被初始化
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            // BeanFactory的预准备工作
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                // 执行BeanFactoryPostProcessor的方法,BeanFactory的后置处理器 
                // 在BeanFactory标准初始化之后执行的
                this.invokeBeanFactoryPostProcessors(beanFactory);
                // 注册BeanPostProcessor(Bean的后置处理器),用于拦截bean创建过程
                this.registerBeanPostProcessors(beanFactory);
                // 初始化MessageSource组件(做国际化功能;消息绑定,消息解析).
                this.initMessageSource();
                // 初始化上下文的事件机制
                this.initApplicationEventMulticaster();
                // 可以用于子类实现在容器刷新时自定义逻辑初始化
                this.onRefresh();
                // 注册时间监听器,将ApplicationListener注册到容器中来
                this.registerListeners();
                // 初始化所有剩下的单实例bean,单例bean在初始化容器时创建。
                this.finishBeanFactoryInitialization(beanFactory);
                // 发布完成事件,结束初始化过程
                this.finishRefresh();
            } catch (BeansException var5) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var5);
                this.destroyBeans();
                this.cancelRefresh(var5);
                throw var5;
            }

        }
    }

obtainFreshBeanFactory将配置文件解析为BeanDefinition并注册到BeanFactory中

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
     // 主要是通过该方法完成IoC容器的刷新
        this.refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }

        return beanFactory;
    }

refreshBeanFactory完成IOC容器的刷新,具体实现是在AbstractRefreshableApplicationContext中,实际创建的的IOC容器为:DefaultListableBeanFactory

protected final void refreshBeanFactory() throws BeansException {
    //首先检查是否已经有beanFactory了,有就销毁
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
          // 创建IoC容器,也就是DefaultListableBeanFactory
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);
            //载入刚创建的IOC容器,具体实现在子类XmlWebApplicationCpntext中
            this.loadBeanDefinitions(beanFactory);
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }

loadBeanDefinitions装载刚创建的IOC容器,具体实现在XmlWebApplicationCpntext中。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 创建一个BeanDefinition阅读器,通过阅读XML文件,真正完成BeanDefinition的加载和注册
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    //beanDefinitionReaderde 初始化操作
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    
        this.initBeanDefinitionReader(beanDefinitionReader);
        this.loadBeanDefinitions(beanDefinitionReader);
    }
//方法重载
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
    /*在上一篇文章中ContextLoader中的configureAndRefreshWebApplicationContext方法有这一段代码
     configLocationParam = sc.getInitParameter("contextConfigLocation");
        if (configLocationParam != null) {
            //保存配置文件信息的位置。
            wac.setConfigLocation(configLocationParam);
        }
        这里就是读取配置文件的信息,保存进数组中。
    */
        String[] configLocations = this.getConfigLocations();
        if (configLocations != null) {
            String[] var3 = configLocations;
            int var4 = configLocations.length;
            for(int var5 = 0; var5 < var4; ++var5) {
                String configLocation = var3[var5];
                //具体的装载方法在XmlBeanDefinitionReader
                reader.loadBeanDefinitions(configLocation);
            }
        }

    }


​ 接下来看XmlBeanDefinitionReader中的loadBeanDefinitions()

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    	// 对配置文件进行编码处理
        return this.loadBeanDefinitions(new EncodedResource(resource));
}
//截取主要代码
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    try {
        //将配置文件转换成流对象
                InputStream inputStream = encodedResource.getResource().getInputStream();

                try {
                    // 从InputStream中得到XML的解析源
                    InputSource inputSource = new InputSource(inputStream);
                    if (encodedResource.getEncoding() != null) {
                        inputSource.setEncoding(encodedResource.getEncoding());
                    }
					 // 这里是具体的读取过程,var5等于新注册的BeanDefintion数量
                    var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
                } finally {
                    inputStream.close();
                }
    
}

​ 具体的读取过程在doLoadBeanDefinitions()中,该方法的主要作用就是:

  • 一个是对XML文件进行DOM解析
  • 一个是完成BeanDefinition对象的加载与注册
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
        try {
            //把资源文件转换成Document对象
            Document doc = this.doLoadDocument(inputSource, resource);
            // 通过对Document对象的操作,完成BeanDefinition的加载和注册工作
            return this.registerBeanDefinitions(doc, resource);
        }Catch(){
		}
    }

​ 看看registerBeanDefinitions()具体完成了哪些操作:

  1. 创建DefaultBeanDefinitionDocumentReader用来解析Document对象。
  2. 获得容器中已注册的BeanDefinition数量
  3. 委托给DefaultBeanDefinitionDocumentReader来完成BeanDefinition的加载、注册工作。
  4. 统计新注册的BeanDefinition数量
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    //  1.
        BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
        documentReader.setEnvironment(this.getEnvironment());
    // 2.
        int countBefore = this.getRegistry().getBeanDefinitionCount();
    // 3. 解析过程入口,BeanDefinitionDocumentReader只是个接口,具体的实现过程在DefaultBeanDefinitionDocumentReader完成
        documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
    // 4.
        return this.getRegistry().getBeanDefinitionCount() - countBefore;
    }

​ 接着看DefaultBeanDefinitionDocumentReader中的registerBeanDefinitions()该方法:

  • 获得Document的根元素标签
  • 真正实现BeanDefinition解析和注册工作
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        this.logger.debug("Loading bean definitions");
    	//获取文档对象的子节点。
        Element root = doc.getDocumentElement();
    	//真正的解析注册方法
        this.doRegisterBeanDefinitions(root);
    }

​ 到这一步接下来就是对解析文档中的每一个标签节点,获取标签中的属性。创建AbstractBeanDefinition对象,并将标签中属性保存进对象中。具体的步骤就不展示了。

​ 综上步骤具体完成了以下操作:

  1. 创建IoC容器(DefaultListableBeanFactory)

  2. 加载解析XML文件(最终存储到Document对象中)

  3. 读取Document对象,并完成BeanDefinition的加载和注册工作

    BeanDefinition 在 spring 中贯穿始终,spring 要根据 BeanDefinition 对象来实

例化 bean,只有把解析的标签,扫描的注解类封装成 BeanDefinition 对象,spring

**才能实例化 bean **

​ 上面的步骤只是完成了AbstractApplicationContext中refresh()这句话(心累…)

ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

2. 实例化Bean对象

​ 进入AbstractApplicationContext中的finishBeanFactoryInitialization()

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
     	// 实例化剩余的单例bean(非懒加载方式)
    	// 注意事项:Bean的IoC、DI和AOP都是发生在此步骤
        beanFactory.preInstantiateSingletons();
    }

进入DefaultListableBeanFactory中的preInstantiateSingletons()方法:

  • 通过beanName获取bean实例,如果获取到的实例不满足条件就看最后一行getBean(beanName);
  • 核心代码 getBean(beanName);
@Override
    public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
        }
        // 得到Bean定义名称
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
        // 触发所有非懒加载方式的单例bean的创建
        for (String beanName : beanNames) {
        // 遍历得到对应的bean定义信息
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 如果bean不是抽象的,而且是单例的,同时还不是懒加载的,则进行下面的操作
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 如果bean是一个工厂bean,则走下面的方法 ,和普通bean区别就是还可以生成bean
                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 { // 普通bean走下面的方法
                    getBean(beanName);
                }
            }
        }

​ 进入AbstractBeanFactory通过doGetBean()方法获取Bean的实例(只展示关键代码)

  1. 通过getSingleton(beanName)方法去缓存中获取单例Bean(第一次初始化,缓存中不存在)

  2. 如果取出来的bean实例是factoryBean的实例,则需要从factoryBean中产生一个Bean对象

  3. 根据当前的beanfactory获取父一级的beanFactory,递归查找我们需要的Bean(Bean是早不到的,第一次初始化)

  4. 获取实例化Bean的BeanDefinition对象

  5. 一般是单例Bean,用匿名内部类的写法,创建单例Bean

    @Override
        public Object getBean(String name) throws BeansException {
            // 获取Bean的实例
            return doGetBean(name, null, null, false);
        }
    
    
    @SuppressWarnings("unchecked")
        protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    
            // 获取bean名称
            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) { //如果获取到单例bean,则走下面代码
                if (logger.isDebugEnabled()) {
                    if (isSingletonCurrentlyInCreation(beanName)) {
                        logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                                "' that is not fully initialized yet - a consequence of a circular reference");
                    }
                    else {
                        logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                    }
                }
                // 如果取出来的Bean实例是FactoryBean的Bean实例,则需要从FactoryBean实例中产生一个对象实例。
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
            }
    
            else {//如果没有获取到单例bean,则走下面代码
                try {
                    // 获取要实例化的bean的BeanDefinition对象
                    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                    // 检查该BeanDefinition对象对应的Bean是否是抽象的
                    checkMergedBeanDefinition(mbd, beanName, args);
    
                    // 如果是单例的Bean,请下面的代码
                    if (mbd.isSingleton()) {                    //匿名内部类的写法
                        sharedInstance = getSingleton(beanName, () -> {
                            try {
                                // 创建单例Bean的主要方法
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                       
                                destroySingleton(beanName);
                                throw ex;
                            }
                        });
                        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                    }
                          return (T) bean;
    }
    

    进一步看看createBean()具体实现在AbstractAutowireCapableBeanFactory

    @Override
        protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                throws BeanCreationException {
    //省略一些代码
        try {
                // 完成Bean实例的创建(实例化、填充属性、初始化)
                Object beanInstance = doCreateBean(beanName, mbdToUse, args);
                if (logger.isDebugEnabled()) {
                    logger.debug("Finished creating instance of bean '" + beanName + "'");
                }
                return beanInstance;
            }
    ****
    
    

    doCreateBean完成Bean实例的创建(实例化、填充属性、初始化)

    • bean初始化第一步,默认调用无参数构造实例化bean
    • bean初始化第二步,填充属性(DI依赖注入发生在此步骤)
    • bean初始化第三步,调用初始化方法,完成bean的初始化操作AOP发生在此步骤)
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
                throws BeanCreationException {
    
            // Instantiate the bean.
            // 用BeanWrapper来持有创建出来的Bean对象
            BeanWrapper instanceWrapper = null;
            // 如果是单例的话,则先把缓存中的bean清除
            if (mbd.isSingleton()) {
                instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
            }
            // bean初始化第一步:默认调用无参构造实例化Bean
            // 构造参数依赖注入,就是发生在这一步
                    // 为了下一步populateBean方法的属性注入做准备
            if (instanceWrapper == null) {
                instanceWrapper = createBeanInstance(beanName, mbd, args);
            }
            // 实例化后的Bean对象
            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));
            // 如果需要提前暴露单例Bean,则将该Bean放入三级缓存中
            if (earlySingletonExposure) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Eagerly caching bean '" + beanName +
                            "' to allow for resolving potential circular references");
                }
                // 将刚创建的bean放入三级缓存中singleFactories(key是beanName,value是FactoryBean)
                addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
            }
    
            // Initialize the bean instance.
            Object exposedObject = bean;
            try {
                // bean初始化第二步:填充属性(DI依赖注入发生在此步骤)
                populateBean(beanName, mbd, instanceWrapper);
                // bean初始化第三步:调用初始化方法,完成bean的初始化操作(AOP发生在此步骤)
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
    ******************************************
    }
    

    进入上面的initializeBean()方法:

    • 应用BeanPostProcessor的postProcessBeforeInitialization方法在初始化之前被调用
    • 执行初始化方法(先调用InitializingBean的afterPropertiesSet,再调用init-method属性指定的初始化方法,最后BeanPostProcessor的postProcessAfterInitialization)
    • 应用BeanPostProcessor的postProcessAfterInitialization方法(AOP代理对象生成)在初始化之后被调用
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }, getAccessControlContext());
            }
            else {
                /*判断beanName是哪个接口的的实现类
            如果bean是BeanNameAware接口的实现类会调用setBeanName方法、
          	如果bean是BeanClassLoaderAware接口的实现类会调用setBeanClassLoader方法、
          	如果是BeanFactoryAware接口的实现类会调用setBeanFactory方法,注入对应的属性值。*/
                invokeAwareMethods(beanName, bean);
            }
    
            Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
                //应用BeanPostProcessor的postProcessBeforeInitialization方法
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
    
            try {
                //执行初始化方法(先调用InitializingBean的afterPropertiesSet,再调用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的postProcessAfterInitialization方法(AOP代理对象生成)
                // AOP是等着对象创建完毕,在进行增强
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
    
            return wrappedBean;
        }
    

    调用初始化方法invokeInitMethods()

    • 判断是否是InitializingBean接口的实现类,如果是县初始化InitializingBean
    • 如果不是则调用InitializingBean接口中的afterPropertiesSet方法
    • 然后再初始化标签对应的init-method属性中的方法
    protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
                throws Throwable {
    
            boolean isInitializingBean = (bean instanceof InitializingBean);
            // 如果是InitializingBean接口的实现类,则先初始化InitializingBean的实现类
            if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
                }
                if (System.getSecurityManager() != null) {
                    try {
                        AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                            ((InitializingBean) bean).afterPropertiesSet();
                            return null;
                        }, getAccessControlContext());
                    }
                    catch (PrivilegedActionException pae) {
                        throw pae.getException();
                    }
                }
                else {
                    // 调用InitializingBean接口的afterPropertiesSet方法
                    ((InitializingBean) bean).afterPropertiesSet();
                }
            }
    
            // 然后再初始化<bean>标签对应的init-method属性中的方法
            if (mbd != null && bean.getClass() != NullBean.class) {
                String initMethodName = mbd.getInitMethodName();
                if (StringUtils.hasLength(initMethodName) &&
                        !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                        !mbd.isExternallyManagedInitMethod(initMethodName)) {
                    // 调用自定义的初始化方法
                    invokeCustomInitMethod(beanName, bean, mbd);
                }
            }
        }
    

    在initializeBean方法中调用BeanPostProcessor的applyBeanPostProcessorsAfterInitialization方法

    • 在初始化Bean的时候都会调用每一个配置的BeanPostProcessor的方法
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
            Object result = existingBean;
            Iterator var4 = this.getBeanPostProcessors().iterator();
    
            do {
                if (!var4.hasNext()) {
                    return result;
                }
    
                BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
                //bean初始化后调用
                result = beanProcessor.postProcessAfterInitialization(result, beanName);
            } while(result != null);
    
            return result;
        }
    

    BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。接口声明如下:

    public interface BeanPostProcessor {
        //bean初始化方法调用前被调用
        Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
        //bean初始化方法调用后被调用
        Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
    }
    
    

    至此bean的初始化就完成了。

tProcessor)var4.next();
//bean初始化后调用
result = beanProcessor.postProcessAfterInitialization(result, beanName);
} while(result != null);

       return result;
   }

BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。接口声明如下:

```java
public interface BeanPostProcessor {
    //bean初始化方法调用前被调用
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    //bean初始化方法调用后被调用
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

至此bean的初始化就完成了。
参考:https://www.jianshu.com/p/32dacf644062 作者:GGarrett

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章