一、代码实例

  如之前介绍的,spring中ioc是它最为核心的模块,前边花了大量时间分析spring的bean工厂和他如何生成bean,可是在我们实际应用中,很少直接使用beanFactory,因为spring提供了更好用的ApplicationContext接口,使用方法和bean工厂基本一致

        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
        Person person=(Person)context.getBean("person");
        person.sayHello();

  那么我们来看下源代码中,我们ClassPathXmlApplicationContext为目标,分析它做了哪些工作。

二、源码分析

  1、进入ClassPathXmlApplicationContext,我们可以看到他提供了各种重构方法,其中配置文件路径可以支持:字符串,可变字符串,数组

    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[] {configLocation}, true, null);
    }
    public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
        this(configLocations, true, null);
    }
    public ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {
        this(configLocations, true, parent);
    }
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
        this(configLocations, refresh, null);
    }

  2、进入refresh方法,首先竹本refresh环境,

    protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        this.closed.set(false);
        this.active.set(true);

        if (logger.isInfoEnabled()) {
            logger.info("Refreshing " + this);
        }

        // Initialize any placeholder property sources in the context environment
        initPropertySources();

        // Validate that all properties marked as required are resolvable
        // see ConfigurablePropertyResolver#setRequiredProperties
        getEnvironment().validateRequiredProperties();

        // Allow for the collection of early ApplicationEvents,
        // to be published once the multicaster is available...
        this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
    }

  3、调用ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

  4、调用refreshBeanFactory方法,可以看到里边的几个步骤

  a)生产beanfactory,如果有父类,继承父类

  b)设置序列化id

  c)customizeBeanFactory,暂时不知道用处

  d)loadBeanDefinitions(beanFactory)最终调用了loadBeanDefinitions(beanDefinitionReader)方法

  可见在此步骤已经完成了对xml文件的读取,并解析为最终的beanDefinition

protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

  5、prepareBeanFactory设置各种BeanFactory的参数

  6、invokeBeanFactoryPostProcessors调用BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的方法

  7、查找是否有initMessageSource为id的bean,如果没有,创建默认的

  8、查找是否有id为applicationEventMulticaster的bean,如果没有,创建默认,设置为congtext的applicationEventMulticaster

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //查找是否包含名为applicationEventMulticaster的bean,如果没有,创建默认的
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        }
        else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                        APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                        "': using default [" + this.applicationEventMulticaster + "]");
            }
        }
    }

  9、查找注册的ApplicationListener,设置到applicationEventMulticaster中

    protected void registerListeners() {
        // Register statically specified listeners first.
        //查找手动设置的ApplicationListener,设置到applicationEventMulticaster中
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let post-processors apply to them!
        //根据beanType查询ApplicationListener,设置到applicationEventMulticaster中
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // Publish early application events now that we finally have a multicaster...
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        //查询是否有需要立即通知的事件,进行通知
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

  10、查找是否有id为conversionService的bean,如果有,设置进beanFactory

        //查找是否有id为conversionService的bean,如果有,设置进beanFactory
        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));
        }

  11、查找是否有embeddedValueResolvers,值的解析器,没有默认注入string解析

        //查找是否有embeddedValueResolvers,值的解析器,没有默认注入string解析
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                @Override
                public String resolveStringValue(String strVal) {
                    return getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }

  12、查找类型为LoadTimeWeaverAware的解析,有的话进行获取,并没有进一步使用,应该只是起到初始化作用

        //查找类型为LoadTimeWeaverAware的解析,有的话进行获取,并没有进一步使用,应该只是起到初始化作用
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

  13、进入preInstantiateSingletons方法,初始化所有的bean

for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //判断是否工厂bean
                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<Boolean>() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    //进行实例化
                    getBean(beanName);
                }
            }
        }

  14、已经初始化的bean,并且继承了SmartInitializingSingleton接口,执行它的afterSingletonsInstantiated方法

//已经初始化的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<Object>() {
                        @Override
                        public Object run() {
                            smartSingleton.afterSingletonsInstantiated();
                            return null;
                        }
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }

  15、调用finishRefresh,完成bean的刷新,第一步initLifecycleProcessor初始化bean的生命后周期bean

protected void initLifecycleProcessor() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //获取id为lifecycleProcessor的bean,如果没有,创建默认的
        if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
            this.lifecycleProcessor =
                    beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
            }
        }
        else {
            DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
            defaultProcessor.setBeanFactory(beanFactory);
            this.lifecycleProcessor = defaultProcessor;
            beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate LifecycleProcessor with name '" +
                        LIFECYCLE_PROCESSOR_BEAN_NAME +
                        "': using default [" + this.lifecycleProcessor + "]");
            }
        }
    }

  16、getLifecycleProcessor().onRefresh()方法,启动特定bean

private void startBeans(boolean autoStartupOnly) {
        Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
        //获取所有继承了Lifecycle的SmartLifecycle,并且自动启动且phase不为空,那么执行start方法
        Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
        for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
            Lifecycle bean = entry.getValue();
            if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
                int phase = getPhase(bean);
                LifecycleGroup group = phases.get(phase);
                if (group == null) {
                    group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                    phases.put(phase, group);
                }
                group.add(entry.getKey(), bean);
            }
        }
        if (phases.size() > 0) {
            List<Integer> keys = new ArrayList<Integer>(phases.keySet());
            Collections.sort(keys);
            for (Integer key : keys) {
                phases.get(key).start();
            }
        }
    }

  17、广播容器刷新事件publishEvent(new ContextRefreshedEvent(this))

protected void publishEvent(Object event, ResolvableType eventType) {
        Assert.notNull(event, "Event must not be null");
        if (logger.isTraceEnabled()) {
            logger.trace("Publishing event in " + getDisplayName() + ": " + event);
        }

        // Decorate event as an ApplicationEvent if necessary
        ApplicationEvent applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent) event;
        }
        else {
            applicationEvent = new PayloadApplicationEvent<Object>(this, event);
            if (eventType == null) {
                eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
            }
        }

        // Multicast right now if possible - or lazily once the multicaster is initialized
        if (this.earlyApplicationEvents != null) {
            //如果有预制行添加到预制行,预制行在执行一次后被置为null,以后都是直接执行
            this.earlyApplicationEvents.add(applicationEvent);
        }
        else {
            //广播event时间
            getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
        }

        // Publish event via parent context as well...
        //父bean同样广播
        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
            }
            else {
                this.parent.publishEvent(event);
            }
        }
    }

  18、到此,我们完成了整个初始化过程,获取bean时候,流程基本不变

三、总结

  我们可以看到,与beanfactory相比,context有以下特点:

  1、在基本的解析文件生成beanDefinition过程其实两者是一致的,都是解析了xml的配置后生成了配置文件放到了beanDefinitionMap中

  2、在beanFactory中的,bean是在第一次getBean的时候进行生成,所以配置lazy-init延迟加载并不会起作用,因为全部bean都是延迟加载的。在context中,会在解析完成后的preInstantiateSingletons方法中调用getBean初始化所有的非lazy-init且单例模式的bean

  3、在context中内置了许多的bean,他们要求开发者必须按照系统约定的命名规则进行命名,这样可以在系统内部组成特定的功能,如果开发者没有定义这些bean,系统也会默认生成一个bean,这些bean主要有:messageSource、applicationEventMulticaster、conversionService、embeddedValueResolvers、lifecycleProcessor,也有一些指定了接口实现的bean如:LoadTimeWeaverAware、SmartInitializingSingleton。这些类完善了bean的整个流程,使得ioc容器可以读取配置文件,管理通知,bean生命周期等

[spring源码学习]七、IOC源码-Context的更多相关文章

  1. spring cloud深入学习(四)-----eureka源码解析、ribbon解析、声明式调用feign

    基本概念 1.Registe 一一服务注册当eureka Client向Eureka Server注册时,Eureka Client提供自身的元数据,比如IP地址.端口.运行状况指标的Uri.主页地址 ...

  2. 【 js 基础 】【 源码学习 】backbone 源码阅读(一)

    最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(https://github.com/JiayiLi/source-code-stud ...

  3. 【 js 基础 】【 源码学习 】backbone 源码阅读(二)

    最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(source-code-study)进行参考交流,有详细的源码注释,以及知识总结,同时 ...

  4. 【 js 基础 】【 源码学习 】backbone 源码阅读(三)浅谈 REST 和 CRUD

    最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(https://github.com/JiayiLi/source-code-stud ...

  5. go 源码学习之---Tail 源码分析

    已经有两个月没有写博客了,也有好几个月没有看go相关的内容了,由于工作原因最近在做java以及大数据相关的内容,导致最近工作较忙,博客停止了更新,正好想捡起之前go的东西,所以找了一个源码学习 这个也 ...

  6. 【 js 基础 】【 源码学习 】backbone 源码阅读(三)

    最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(https://github.com/JiayiLi/source-code-stud ...

  7. Jetty源码学习-编译Jetty源码二三事

    工作小几个月了,JDK基础和web应用框架学的的差不多了,开始学习Jetty源码,费了小半天才编译成功,把自己拆过的坑记录下来. 编译前的环境: MAVEN 3.3.Eclips eLuna Serv ...

  8. Spring源码学习之IOC容器实现原理(一)-DefaultListableBeanFactory

    从这个继承体系结构图来看,我们可以发现DefaultListableBeanFactory是第一个非抽象类,非接口类.实际IOC容器.所以这篇博客以DefaultListableBeanFactory ...

  9. Spring源码学习之IOC实现原理(二)-ApplicationContext

    一.Spring核心组件结构 总的来说Spring共有三个核心组件,分别为Core,Context,Bean.三大核心组件的协同工作主要表现在 :Bean是包装我们应用程序自定义对象Object的,O ...

随机推荐

  1. hibernate学习笔记之四 Hibernate的增删改查

    采用JUnit测试,继承TestCase import java.util.Date; import junit.framework.TestCase; import org.hibernate.Se ...

  2. python3使用pyqt5制作一个超简单浏览器

    我们使用的是QWebview模块,这里也主要是展示下QWebview的用法. 之前在网上找了半天的解析网页的内容,都不是很清楚. 这是核心代码: webview = Qwebview() webvie ...

  3. java源代码跟踪

    首先我们要学会的是将JDK源码加载Eclipse中. 1.点“窗口”——>"首选项",选择左边的"Java"——>"已安装的JRE&quo ...

  4. 【转】HTTP协议详解

    原文地址:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436.html 一.概念 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则 ...

  5. Ext-设置form表单不可编辑

    1. var formEach = win.down('form').items.items; Ext.each(formEach,function(item){ console.log(item); ...

  6. selenium + python 添加等待时间

    转载于:http://www.blogjava.net/qileilove/articles/412450.html 四.添加等待时间 有时候为了保证脚本运行的稳定性,需要脚本中添加等待时间. 4.1 ...

  7. 《WPF程序设计指南》读书笔记——第3章 内容的概念

    1.Content属性及字体相关的属性 using System; using System.Windows; using System.Windows.Media; namespace LY.Dis ...

  8. nhibernate 3.3 linq扩展

    nhibernate的sqlserver linq 全文检索搞了半天 方法一 ,扩展LinqToHqlGeneriatorsRegistry http://www.cnblogs.com/xiarug ...

  9. sql发邮件

    DROP PROCEDURE USP_CheckProductCodeRepeatAndSendMail go ---检查商家是否有重复的商品编号,如果有则发送给系统配置中接收的用户邮箱 CREATE ...

  10. escape,encodeURI,encodeURIComponent

    JavaScript/js中,有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,d ...