Spring Refresh() 简析

Spring IOC容器分为两部分:创建、实例化


引言
pom.xml中引入(引入当前即可,会自动把spring其他基础jar包引入):

 
    org.springframework 
    spring-context 
    4.3.11.RELEASE 


然后使用:
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
继承体系如下:
Spring Refresh() 简析_第1张图片
使用例子:
//获取bean  当前context就是上面拿到的ApplicationContext
MessageService messageService = context.getBean(MessageService.class);
messageService.getMessage();
-applicationContext.xml为:





    

BeanFactory简介
作用:负责生产和管理bean实例。

 

1 BeanFactory(org.springframework.beans.factory):

作用:提供最基础的容器查看的功能,保存了bean的定义,并且可以根据不同条件获取bean,查看bean是否单利,获取bean的别名。有一个&用来表示获取工厂本身而不是获取到工厂的实例。

 

学到了什么?

    bean生命周期:一堆接口->init-method->BeanPostProcessors接口(一切就绪之后的接口)->destory-method()。

    可给bean指定别名。

    bean工厂有层级关系,找bean过程是:从子到父。

 

2 ListableBeanFactory(org.springframework.beans.factory):

作用:返回一系列bean,根据不同的条件获取。

 

学到了什么?

    提供了list的bean工厂,可以枚举每一个bean定义。或者获取bean信息或者bean的实例。使用时不需要考虑已经注册了的bean和层级关系。

 

3 EnvironmentCapable(org.springframework.core.env):

作用:实现spring上下文的接口,获取上下文。可通过如下获取:

Environment getEnvironment();

 

4 HierarchicalBeanFactory:层级分层


启动过程分析
先从入口类ClassPathXmlApplicationContext.java看起:

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {


    private Resource[] configResources;
    
    public ClassPathXmlApplicationContext() {
    }
  // 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
    public ClassPathXmlApplicationContext(ApplicationContext parent) {
        super(parent);
    }
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
        throws BeansException {
        super(parent);
         // 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();  //重点!!!
        }
    }
    @Override
    protected Resource[] getConfigResources() {
        return this.configResources;
    }
    .....................
    .....................
}




refresh()将原来ApplicationContext销毁后重新执行初始化操作,其代码如下(AbstractApplicationContext.java 446):

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
    // 准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写 
    prepareRefresh();


    // 这步比较重要(解析),告诉子类去刷新bean工厂,这步完成后配置文件就解析成一个个bean定义,注册到BeanFactory(但是未被初始化,仅将信息写到了beanDefination的map中)
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();


    // 设置beanFactory类加载器,添加多个beanPostProcesser
    prepareBeanFactory(beanFactory);


    try {
        // 允许子类上下文中对beanFactory做后期处理
        postProcessBeanFactory(beanFactory);


        // 调用BeanFactoryPostProcessor各个实现类的方法
        invokeBeanFactoryPostProcessors(beanFactory);


        // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
        registerBeanPostProcessors(beanFactory);


        //初始化ApplicationContext的MessageSource
        initMessageSource();


        //初始化ApplicationContext事件广播器
        initApplicationEventMulticaster();


        // 初始化子类特殊bean(钩子方法)
        onRefresh();


        // 注册事件监听器
        registerListeners();


        // 初始化所有singleton bean  重点!!重点!!
        finishBeanFactoryInitialization(beanFactory);


        // 广播事件,ApplicationContext初始化完成
        finishRefresh();
} catch (BeansException ex) {
....................
}




refresh详细流程解析如下:
1 prepareRefresh():准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写。


2 obtainFreshBeanFactory()
-(AbstractApplicationContext.java 536):重要!!==>初始化beanFactory,注册Bean

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    //刷新上下文环境,关闭旧的beanFactory,并创建新的
    refreshBeanFactory();
    //返回刚创建的beanFactory  (return this.beanFactory;)
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}



2.1 obtainFreshBeanFactory()->refreshBeanFactory()
-(AbstractRefreshableApplicationContext.java 120):

@Override
protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) { //关闭旧的beanFactory
        destroyBeans();
        closeBeanFactory();
    }
    try {//创建新的beanFactory(创建的是DefaultListableBeanFactory)
        DefaultListableBeanFactory beanFactory = createBeanFactory();  
        beanFactory.setSerializationId(getId());  //然后重新设置在closeBeanFactory()置为null的serialzationId
        customizeBeanFactory(beanFactory);  //自定义beanFactory,设置是否允许覆盖、是否循环引用标识
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
        this.beanFactory = beanFactory;
    }
} catch........................................
}


2.1.1 obtainFreshBeanFactory()->refreshBeanFactory()->destroyBeans()
-(AbstractApplicationContext.java 907):

protected void destroyBeans() {
    getBeanFactory().destroySingletons();
}


销毁所有beans,默认实现是销毁所有缓存的单例。这里提供了一个模板方法模式,在DefaultListableBeanFactory.java、DefaultSingletonRegistry.java做了具体的实现。其中DefaultListableBeanFactory 实现了基本实现了上层所有接口含注解的AbstractAutowireCapableBeanFactory.java,所以DefaultListableBeanFactory是最牛逼的BeanFactory。


2.1.2 obtainFreshBeanFactory()->refreshBeanFactory()->closeBeanFactory()
-(AbstractRrefreshableApplicationContext.java 149):

protected final void closeBeanFactory() {
    synchronized (this.beanFactoryMonitor) {
        this.beanFactory.setSerializationId(null);
        this.beanFactory = null;
    }
}


将beanFactory和serializationId设置为null。


2.1.3 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations()  !!重要!!
-(AbstractRrefreshableApplicationContext.java 80):
根据配置加载各个bean,然后放到BeanFactory中

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 将beanFactory传入XmlBeanDefinitionReader中,并解析、加载配置
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);


    // 配置beanDefination,环境资源加载如
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));


    //加载beanFactory 重要!!
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}




2.1.3.1 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations()->loadBeanDefinitions()
-(AbstractXmlApplicationContext.java 120):

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    Resource[] configResources = getConfigResources();  //新建一个ClassPathResource
    if (configResources != null) {
        reader.loadBeanDefinitions(configResources); //加载beandefation
    }
    String[] configLocations = getConfigLocations();//加载beandefation
    if (configLocations != null) {
        reader.loadBeanDefinitions(configLocations);
    }
}




2.1.3.1.1 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations()->loadBeanDefinitions()->getConfigResources()
-(ClassPathXmlApplicationContext.java 202):

protected Resource[] getConfigResources() {
    return this.configResources;
}




2.1.3.1.1 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations()->loadBeanDefinitions()->loadBeanDefinitions()
-(AbstractBeanDefinitionReader.java 177):

public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    Assert.notNull(resources, "Resource array must not be null");
    int counter = 0;
    for (Resource resource : resources) {
        counter += loadBeanDefinitions(resource);  //调用了XmlBeanDefintionReader.java的loadBeanDefinitions
    }
    return counter;
}


上面会一个个加载并返回加载的数量。


2.1.3.1.1.1 obtainFreshBeanFactory()->refreshBeanFactory()->loadBeanDefinations()->loadBeanDefinitions()->loadBeanDefinitions()->loadBeanDefinitions()
-(XmlBeanDefinitionReader.java 303):

@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(new EncodedResource(resource));
}


/**
* 从指定xml解析beanDefination
*/
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    ....................................
    //使用ThreadLocal存放配置文件资源
    Set currentResources = this.resourcesCurrentlyBeingLoaded.get();
    if (currentResources == null) {
        currentResources = new HashSet(4);
        this.resourcesCurrentlyBeingLoaded.set(currentResources);
    }
    ........................................
    try {
            InputStream inputStream = encodedResource.getResource().getInputStream();
            try { 
                //装饰者模式包装
                InputSource inputSource = new InputSource(inputStream);
                if (encodedResource.getEncoding() != null) {
                    inputSource.setEncoding(encodedResource.getEncoding());
                }
                //真实从指定xml解析beanDefination  !重点!
                return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            }
            ..................................
        } catch (IOException ex) {
            ...................................
        } finally {
            .............................
        }
}


//==>真实从指定xml解析beanDefination===========================
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    throws BeanDefinitionStoreException {
    try {
        //将xml转为document对象
        Document doc = doLoadDocument(inputSource, resource);
        //用给定的dom文档注册beanDefinition
        return registerBeanDefinitions(doc, resource);
    }catch............................
}




接下来的解析过程就不详细探讨,到这里初始化了bean容器,将xml配置转成BeanDefinition,并注册了,发送了注册事件。
上面讲完了refresh()的obtainFreshBeanFactory()如下:
Spring Refresh() 简析_第2张图片
接下来我们继续往下看:

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
    // 准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写 
    prepareRefresh();


    // 这步比较重要(解析),告诉子类去刷新bean工厂,这步完成后配置文件就解析成一个个bean定义,注册到BeanFactory(但是未被初始化,仅将信息写到了beanDefination的map中)
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();


    // 设置beanFactory类加载器,添加多个beanPostProcesser
    prepareBeanFactory(beanFactory);


    try {
        // 允许子类上下文中对beanFactory做后期处理
        postProcessBeanFactory(beanFactory);


        // 调用BeanFactoryPostProcessor各个实现类的方法
        invokeBeanFactoryPostProcessors(beanFactory);


        // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
         // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
         // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
        registerBeanPostProcessors(beanFactory);


        //初始化ApplicationContext的MessageSource
        initMessageSource();


        //初始化ApplicationContext事件广播器
        initApplicationEventMulticaster();


        // 初始化子类特殊bean(钩子方法)
        onRefresh();


        // 注册事件监听器
        registerListeners();


        // 初始化所有singleton bean  重点!!重点!!
        finishBeanFactoryInitialization(beanFactory);


        // 广播事件,ApplicationContext初始化完成
        finishRefresh();
} catch (BeansException ex) {
....................
}


上面的基本注释已经很明显了,所以可跳过上面的直接将finishBeanFactoryInitialization(),这步负责初始化所有singleton bean。


3 finishBeanFactoryInitialization()
-AbstractApplicationContext.java 736

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化名字为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));
    }


    // 初始化LoadTimeWeaverAware相关bean
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }


    // 停止使用临时类加载器进行类型匹配,置null
    beanFactory.setTempClassLoader(null);


    // 冻结(this.configurationFrozen = true;)所有beanDefinition,不让bean继续注册
    beanFactory.freezeConfiguration();


    // 实例化所有剩余的(非延迟-init)单例
    beanFactory.preInstantiateSingletons();
}
//---------------------------------
// 实例化所有剩余的(非延迟-init)单例
public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
    }


    // 拿到所有beanName 去遍历
    List beanNames = new ArrayList(this.beanDefinitionNames);


    // 触发所有非懒加载的singleton bean的初始化
    for (String beanName : beanNames) {
        //将非RootBeanDefinition转换为RootBeanDefinition以方便后续操作,
        //因为Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        //如果当前“不是抽象类 && 是单例 && 不是延迟加载” 则执行
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) { //判断是否factoryBean
                //返回一个共享或独立的实例
                final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
                boolean isEagerInit;
                //安全管理器部分,先不管他,有兴趣可去看
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                    isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
                        @Override
                        public Boolean run() {
                            return ((SmartFactoryBean) factory).isEagerInit();
                        }
                    }, getAccessControlContext());
                } else {
                    isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit());
                }
                if (isEagerInit) {
                    //返回一个实例
                    getBean(beanName);
                }
            } else {
                getBean(beanName);
            }
        }
    }
    // 为所有适合的bean触发初始化后回调
    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() {
                    @Override
                    public Object run() {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }
                }, getAccessControlContext());
            } else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}


//进行实例bean的方法,调用getBean方法最后调到doGetBean
//-返回一个指定bean的实例,无论是共享或独立
protected  T doGetBean(final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
    //去掉beanName前的'&',然后再拿当前beanName去别名aliasMap.get(canonicalName)取
    final String beanName = transformedBeanName(name);
    Object bean;


    // 检查是否已创建过 ,并根据注册给定的名字返回singleton
    Object sharedInstance = getSingleton(beanName);
    //args为空时是获取bean,不为空是创建bean
    if (sharedInstance != null && args == null) { 
        .........................
        //返回对象bean实例,如果是(beanInstance instanceof FactoryBean),则直接返回
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
    //检查当前bean是否已被创建,是则抛异常
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }


        // 检查bean definition是否在该工厂已创建
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // 没找到就去找parent容器
            String nameToLookup = originalBeanName(name);
            if (args != null) {
                // 返回父容器(带参数)
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            } else {
                // 不带参数
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }
        //typeCheckOnly为true时,将指定的bean标记为已创建,添加进Set alreadyCreated中
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }


        try {
            //因为Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            //检查是否Abstract,是则抛异常
            checkMergedBeanDefinition(mbd, beanName, args);


            // 获取以来的所有bean
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                //然后遍历传入进行初始化
                for (String dependsOnBean : dependsOn) {
                    if (isDependent(beanName, dependsOnBean)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                    }
                    registerDependentBean(dependsOnBean, beanName);
                    getBean(dependsOnBean);
                }    
            }


            // 接下来就到了创建一个bean实例的过程,创建单例/多例
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory() {
                    @Override
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        } catch (BeansException ex) {
                            。。。。。。。。。。。。。。。。
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }  else if (mbd.isPrototype()) {  //多例
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                } finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {  //非单例/多例处理
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, new ObjectFactory() {
                        @Override
                        public Object getObject() throws BeansException {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            } finally {
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException ex) {
                    ...........
                }
            }
        } catch (BeansException ex) {
            ...........
        }
    }


    // 检查所需的类型是否与实际bean实例的类型匹配。不是则抛出异常
    if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
        try {
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        } catch (TypeMismatchException ex) {
            .............
        }
        return (T) bean;
    }
} 
  



 

你可能感兴趣的:(JAVA)