spring上下文

作者: binecy | 来源:发表于2018-01-11 17:45 被阅读19次

    源码分析基于spring 4.3.x

    前面已经说过spring 创建bean的过程, 也强调了BeanPostProcessor这些扩展接口。

    在 创建bean过程中, spring会查找用户定义的BeanPostProcessor并进行相应操作, 那么问题来了, 用户定义的BeanPostProcessor是怎样进入spring的呢?
    这里就要说到spring context了。

    我们先来看看spring 模块

    spring-modules.png
    (图片出自 Framework Modules

    Spring-core和Spring-beans模块提供了spring的框架基础,包括IoC和依赖注入功能。

    Context(spring-context)模块建立在Core和Beans模块提供的可靠基础之上。Context模块增加了对国际化(例如使用资源包),事件传播,资源加载,上下文透明创建(如Servlet容器)的支持。Context模块还支持Java EE功能,如EJB,JMX和基本的远程处理。ApplicationContext接口是Context模块的焦点。

    将用户定义的BeanPostProcessor加载到spring,正是spring context的工作。

    回顾一下在spring加载配置中说到的测试例子, 修改为如下就可以使用到spring context了:

    @Test
    public void test() {
        ClassPathXmlApplicationContext beanFactory = new ClassPathXmlApplicationContext("spring.xml");
        Blog bean = (Blog)beanFactory.getBean("blog");
        Assert.assertEquals(bean.getTitle(), "hello spring");
    }
    

    ClassPathXmlApplicationContext的继承层次很深, spring一般按功能的叠加会划分继承关系。


    applicationContext.png

    context可以简单分为web上下文, 非web的上下文。
    这里直接看看例子中的ClassPathXmlApplicationContext

    先看看构造方法

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

    核心方法为refresh(),这个方法在AbstractApplicationContext中

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 准备刷新上下文环境
            prepareRefresh();
    
            // 初始化BeanFactory,并读取xml文件
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
            // 对beanFacotry进行配置
            prepareBeanFactory(beanFactory);
    
            try {
                // 提供给子类覆盖方法做额外处理
                postProcessBeanFactory(beanFactory);
    
                // 激活BeanFactoryPostProcessors
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // 注册BeanPostProcessors
                registerBeanPostProcessors(beanFactory);
    
                initMessageSource();
    
                // 初始化广播器,并放到上下文中   
                initApplicationEventMulticaster();
    
                // 提供给子类初始化其他的Bean
                onRefresh();
    
                // 注册事件监听器
                registerListeners();
    
                // 初始化剩下的非惰性单例bean
                finishBeanFactoryInitialization(beanFactory);
    
                // 完成刷新过程,通知生命周期处理器
                finishRefresh();
            }
            catch (BeansException ex) {
                ...
            } finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }
    

    初始化BeanFactory,读取context文件

    obtainFreshBeanFactory负责初始化BeanFactory,并读取context文件

    初始化BeanFactory

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        return beanFactory;
    }
    

    关键方法是refreshBeanFactory, getBeanFactory只是获取创建好的BeanFactory,refreshBeanFactory由AbstractRefreshableApplicationContext实现

    protected final void refreshBeanFactory() throws BeansException {
        // 如果BeanFactory已存在,则销毁
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            // 创建beanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();   
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
            // 读取xml
            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);
        }
    }
    
    
    protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }
    

    前面已经说过了, spring加载配置主要就是通过DefaultListableBeanFactory。

    读取context文件

    在看看读取xml文件的方法loadBeanDefinitions(DefaultListableBeanFactory beanFactory),该方法由AbstractXmlApplicationContext实现

    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 创建XmlBeanDefinitionReader
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    
        // 配置XmlBeanDefinitionReader
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    
        // 模板方法
        initBeanDefinitionReader(beanDefinitionReader);
        // 读取xml文件
        loadBeanDefinitions(beanDefinitionReader);
    }
    

    这里的loadBeanDefinitions(XmlBeanDefinitionReader reader)由AbstractXmlApplicationContext实现

    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        // getConfigResources模板方法,提供子类扩展
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        // 获取用户指定的context文件
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }
    }
    

    这里通过XmlBeanDefinitionReader.loadBeanDefinitions读取xml文件, 并将结果加载到spring中(在spring加载配置中已经说过了)。

    激活BeanFactoryPostProcessors

    BeanFactoryPostProcessor也是spring提供的扩展接口,可以通过BeanFactoryPostProcessor对beanFactory进行处理,如修改其他BeanDefinition的配置。

    这里会调用AbstractApplicationContext.invokeBeanFactoryPostProcessors

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
        ...
    }
    

    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors会找到用户定义的BeanFactoryPostProcessor,并调用它们。

    注册BeanPostProcessors

    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
    

    PostProcessorRegistrationDelegate.registerBeanPostProcessors会找到用户定义的BeanPostProcessor, 并注册到spring中, spring创建bean时会使用到它们。

    初始化事件广播器

    Spring事件体系包括三个组件:事件ApplicationEvent,事件监听器ApplicationListener,事件广播器ApplicationEventMulticaster。事件广播器负责管理事件监听器,并将事件广播给监听器。

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // beanFactory中包含了事件广播器
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {   
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        }
        else {  // 使用默认的事件广播器
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        }
    }
    

    注册事件监听器

    事件监听器负责监听事件,并做出处理。
    registerListeners将初始化事件监听器,并添加到事件广播器上。

    protected void registerListeners() {
        // 首先注册静态指定的侦听器
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }
    
        // 注册spring上下文中的ApplicationListener
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }
    
        // 发布在此之前已发生的事件
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }
    

    初始化非惰性单例bean

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 初始化ConversionService
        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));
        }
    
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                @Override
                public String resolveStringValue(String strVal) {
                    return getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }
    
        // 初始化LoadTimeWeaverAware
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }
    
        beanFactory.setTempClassLoader(null);
    
        beanFactory.freezeConfiguration();
    
        // 初始化非惰性单例bean
        beanFactory.preInstantiateSingletons();
    }
    

    finishRefresh

    protected void finishRefresh() {
        // 初始化LifecycleProcessor
        initLifecycleProcessor();
    
        // 触发LifecycleProcessor.onRefresh()
        getLifecycleProcessor().onRefresh();
    
        // 发布事件
        publishEvent(new ContextRefreshedEvent(this));
    
        // Participate in LiveBeansView MBean, if active.
        LiveBeansView.registerApplicationContext(this);
    }
    

    LifecycleProcessor也是spring提供的扩展点, 它可以定义spring启动(start),停止(stop),或刷新(onRefresh)时的额外操作。

    protected void initLifecycleProcessor() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
            this.lifecycleProcessor =
                    beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        }
        else {  // 使用默认的LifecycleProcessor
            DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
            defaultProcessor.setBeanFactory(beanFactory);
            this.lifecycleProcessor = defaultProcessor;
            beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        }
    }
    

    这里主要讲了spring context事件传播,上下文创建, 加载扩展接口等内容,讲的比较简单,很多地方都是蜻蜓点水, 有兴趣的同学可以自行深入阅读源码。

    相关文章

      网友评论

        本文标题:spring上下文

        本文链接:https://www.haomeiwen.com/subject/buyznxtx.html