Spring IoC容器初始化

Spring IoC容器初始化详解

环境说明

0.基于Spring3.2.7版本;
1.基于ApplicationContext context = new ClassPathXmlApplicationContext(path);容器;
2.本文的一些术语词汇以及类图关系可结合Spring IoC容器结构一节参考阅读。

详细执行过程:

1.new ClassPathXmlApplicationContext(path):

源码实现如下

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[]{configLocation}, true, (ApplicationContext)null);//默认parent = null;
}

调用的下面这个构造函数:

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
    super(parent);
    this.setConfigLocations(configLocations);
    if(refresh) {
        this.refresh();
    }
}

(1).super(parent);//设置父上下文,继承自AbstractApplicationContext抽象类,默认为null;
(2).this.setConfigLocations(configLocations);//解析路径(占位符,通配符),设置存储配置文件路径;参数等于空则使用默认路径;
(3).可以看到,真正初始化工作是由refresh()方法执行的,它的实现在AbstractApplicationContext抽象类中,源码如下:

public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        //1.初始化准备工作
        this.prepareRefresh();
        //2.创建Bean工厂
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        //3.配置上下文环境,比如类装载器、PostProcessor
        this.prepareBeanFactory(beanFactory);

        try {
            //4.模板方法,为容器某些子类扩展功能所用(工厂后处理器)
                //这里可以参考BeanFactoryPostProcessor接口的postProcessBeanFactory方法
            this.postProcessBeanFactory(beanFactory);
            //调用所有BeanFactoryPostProcessor注册为Bean
            this.invokeBeanFactoryPostProcessors(beanFactory);
            //注册所有实现了BeanPostProcessor接口的Bean
            this.registerBeanPostProcessors(beanFactory);
            //初始化MessageSource,和国际化相关
            this.initMessageSource();
            //初始化容器事件传播器
            this.initApplicationEventMulticaster();
            //调用容器子类某些特殊Bean的初始化,模板方法
            this.onRefresh();
            //为事件传播器注册监听器
            this.registerListeners();
            //初始化所有剩余的bean(普通bean)
            this.finishBeanFactoryInitialization(beanFactory);
            //初始化容器的生命周期事件处理器,并发布容器的生命周期事件
            this.finishRefresh();
        } catch (BeansException var5) {
            //销毁已创建的bean
            this.destroyBeans();
            //取消refresh操作,如重置容器同步标识(prepareRefresh方法中)
            this.cancelRefresh(var5);
            throw var5;
        }
    }
}

  上面的方法,有的是在AbstractApplicationContext已经实现了,有的则是抽象方法(模板方法),供子类自己实现,实现多样化,多态化(模板设计模式)。

2.refresh()方法

1.prepareRefresh()
  容器初始化之前预处理工作,包括记录开始时间,设置容器同步标识等,源码如下:

protected void prepareRefresh() {
        //记录容器开始初始化时间
        this.startupDate = System.currentTimeMillis();
        Object var1 = this.activeMonitor;
        synchronized(this.activeMonitor) {
            this.active = true;//设置容器同步标识
        }

        if(this.logger.isInfoEnabled()) {
            this.logger.info("Refreshing " + this);
        }
        //空方法,由子类覆盖实现,初始化容器上下文中的property文件
        this.initPropertySources();
        this.getEnvironment().validateRequiredProperties();
    }

执行后,在后台提示信息:

八月 12, 2016 5:19:48 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@27b4fe4d: startup date [Fri Aug 12 17:19:48 CST 2016]; root of context hierarchy

2.obtainFreshBeanFactory()
  关闭前面所有 bean 工厂,为新的上下文环境初始化一个新的 bean 工厂。这里需要子类来 协助完成资源位置定义 ,bean 载入和向 IoC 容器注册的过程。源码如下:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        //刷新容器
        refreshBeanFactory();
        //获得新的容器(在上面refreshBeanFactory方法中创建)
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

  关键refreshBeanFactory方法,这是个模板方法,真正实现在子类AbstractRefreshApplicationContext中,其实现如下:

protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {//判断是否已有BeanFactory容器,有,则销毁这上面的bean,并关闭容器
            destroyBeans();
            closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();//创建新的容器
            beanFactory.setSerializationId(getId());
            //定制容器,设置启动参数(bean可覆盖、循环引用),开启注解自动装配
            customizeBeanFactory(beanFactory);
                //将所有BeanDefinition载入beanFactory中,模板方法,具体由子类实现
            loadBeanDefinitions(beanFactory);
            //beanFactory同步
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

  loadBeanDefinitions()这个方法由AbstractXmlApplicationContext提供了一个实现,其实现具体又由AbstractBeanDefinitionReader提供,其主要工作是:将文件变为Resource,再将Resource转化为BeanDefinition(通过XML DOM方式解析),随后存储到beanFactory的BeanDefinitionMap中(这里的bean都是普通bean)。详细步骤可参考:Spring IOC源码详解之容器初始化(小鱼)
  执行该步骤后,控制台打印相关日志信息:

八月 12, 2016 5:19:48 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [/Users/fuchaochao/joy/spring-test2/target/classes/config/spring/local/appcontext-service.xml]

3.prepareBeanFactory()
  设置bean的类加载器,扫描并添加ApplicationContextAwareProcessor(注入实现ApplicationContextAware/ResourceLoaderAware/ApplicationEventPublisherAware/MessageSourceAware接口的bean),为bean添加相应环境(以后可能要读取各种环境的配置属性)。关于Spring的环境(Environment)可以参考:Spring3.1新属性管理API:PropertySource、Environment、Profile(zhang)

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //设置bean类加载器
        beanFactory.setBeanClassLoader(getClassLoader());
        //设置Spring语言表达式(SpEL)解析器
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        //扫描ApplicationContextAware bean
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        //注册类加载期类型切面织入(AOP)LoadTimeWeaver
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        //为各种加载进入beanFactory的bean配置默认环境
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

4.postProcessBeanFactory()
  这里注意和下一步区分,这里的postProcessBeanFactory是模板方法,是提供给子类实现的,子类可以有自己的特殊对BeanDefinition后处理方法,即子类可以在这对前面生成的BeanDefinition,即bean的元数据再处理。比如修改某个bean的id/name属性、scope属性、lazy-init属性(只要是配置文件上面可配置属性均可修改)等。
5.invokeBeanFactoryPostProcessors()
  调用所有BeanFactoryPostProcessor,它同样是一个接口,实现了此接口的类需重写postProcessBeanFactory()这个方法,是的,和第4步作用是一样的,不过这里可以看出,是作为一个接口,提供给用户(开发者)对BeanDefinition做再处理。
6.registerBeanPostProcessors()
  注册实现了BeanPostProcessor接口的bean,BeanPostProcessor这个接口的作用是让开发者通过重写其两个方法,从而对bean初始化(所有普通bean)前后做相关操作。源码如下:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        //获得所有实现了BeanPostProcessor的bean的name
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        //添加并实例化一个BeanPostProcessor,这个是用来记录一些信息的
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // 按是否实现了PriorityOrdered,Ordered以及其他区分这些BeanPostProcessor
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        for (String ppName : postProcessorNames) {
            if (isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
            else if (isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 首先注册实现了PriorityOrdered的,这些的bean的两个方法也会优先被执行
        OrderComparator.sort(priorityOrderedPostProcessors);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // 其次是实现了Ordered接口的
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        OrderComparator.sort(orderedPostProcessors);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // 再之后,是其他的
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // 最后,是所有内部的BeanPostProcessor
        OrderComparator.sort(internalPostProcessors);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
    }

7.initMessageSource()
  初始化消息处理源,如果没有定义,则使用默认的。

protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();//获得当前容器
        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {//判断是否有实现了MessageSource的bean,有则获取并注册
            this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
            // 若该bean实现HierarchicalMessageSource接口,并且本容器的父容器不为空
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    // 设置的MessageSource的父级为空
                    // 设置默认的父级(父MessageSource),如果父容器存在MessageResource则以此为默认,否则以父容器为默认(父容器本身就是一个MessageResource)
                    hms.setParentMessageSource(getInternalParentMessageSource());
                }
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Using MessageSource [" + this.messageSource + "]");
            }
        }
        else {
            //使用一个空的MessageResource处理消息
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
                        "': using default [" + this.messageSource + "]");
            }
        }
    }

8.initApplicationEventMulticaster()
  初始化容器事件传播器(或广播器),其逻辑同第7步,即先检查是否有自定义的ApplicationEventMulticaster,有则从beanFactory中的BeanDefinitionMap中获取并注册,否则创建一个默认的传播器,即SimpleApplicationEventMulticaster。
9.onRefresh()
  模板方法,供子类实现其特殊的容器初始化工作。
10.registerListeners()
  注册那些声明为bean的监听器(注册到前面的事件传播器上),即实现了ApplicationListener接口的,这里不会涉及到其他监听器。关于Spring的事件可以参考:Spring事件体系(caihaijiang)
11.finishBeanFactoryInitialization()
  实例化剩余的所有单例bean(单例bean,且lazy-init=false,在容器初始化时就实例化,以后可直接取用)。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory 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));
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        //停止使用临时的类加载器(加载bean时设置)
        beanFactory.setTempClassLoader(null);

        // 冰冻配置,之后无法更改BeanDefinition元数据
        beanFactory.freezeConfiguration();

        // 初始化所有单例非延迟bean(singleton&lazy-init==false)
        beanFactory.preInstantiateSingletons();
    }

执行这步骤后,控制台输出:

八月 15, 2016 4:54:54 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@7e8a8fc4: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,helloWorld,com.fcc.spring.test.InitBeanPostProcessor#0,com.fcc.spring.test.InstanceBeanPostProcessor#0,com.fcc.spring.test.BeanFactoryPostProcessorTest#0,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy

12.finishRefresh()
  初始化最后步骤,将容器初始化这个工作作为一个事件发布出去,并通过事件传播器传播出去。
13.destroyBeans()
  容器初始化出错,将本容器所管理的bean摧毁,但是容器并没有摧毁,还是激活状态。
14.cancelRefresh()
  将第一步的容器同步标识active设置为false。

总结

本节总结

Spring容器,指的就是IoC容器,其初始化步骤为:
1.创建容器对象,设置父容器、配置文件;
2.容器预处理,主要是设置容器同步标识(标识当前容器是否激活);
3.关闭旧容器,读取配置文件,将其普通bean的元数据BeanDefinition注册到beanFactory中;(bean这个时候并没有实例化)
4.针对子类的或用户自定义的,执行postBeanPostProcessor方法,对BeanDefinition做后处理工作;
5.注册BeanPostProcessor;
6.初始化MessageResource;
7.初始化事件传播器;
8.子类自有容器初始化工作;
9.注册监听器bean;
10.实例化单例非延迟bean;
11.发布容器生命周期事件。

最后

  很多东西自己也没搞得很懂,这里只是个大概的流程,大家边看着边查边验证吧,以后自己慢慢熟悉再慢慢更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值