spring 源码-context(一)

 2019-10-17 21:46  阅读(907)
文章分类:Spring boot

1 spring-context 模块概要

该模块主要实现在spring-beans 模块的扩展,主要对aop支持及el表达式的实现
20191017100119\_1.png

分析示例

public static void main(String[] args){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");

        TestBean testBean = (TestBean) context.getBean("testBean");
        testBean.test();
        System.out.println(testBean);
      }

xml配置
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

      <aop:aspectj-autoproxy proxy-target-class="false"/>
      <bean id="testBean" class="com.xie.java.aop.TestBean"/>
      <bean id="aspectJTest" class="com.xie.java.aop.AspectJTest"/>
    </beans>

从ClassPathXmlApplicationContext 入手,先看下该类的继承结构
20191017100119\_2.png

2 applicationcontext 初始化

从上面来看该类继承还是非常复杂的,不管怎么样,先从调用的地方入手

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, boolean refresh, ApplicationContext parent)
                throws BeansException {

            super(parent);
            //处理配置资源初始化
            setConfigLocations(configLocations);
            if (refresh) {
                //这是真正的核心入口
                refresh();
            }
        }

上面都是一些非常简单的代码,无需多解释,接下来主要是看AbstractApplicationContext.refresh方法,context 绝大部分功能由AbstractApplicationContext去实现,下面是主线实现代码,包括利用beanfactory加载beandefinitions 及实例化这些beans 以及aop的实现

@Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                //刷新前一些准备
                prepareRefresh();
                //获得beafactory,并加载beandefinition
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
                //准备一下beanfactory的信息
                prepareBeanFactory(beanFactory);
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    postProcessBeanFactory(beanFactory);

                    // Invoke factory processors registered as beans in the context.
                    //调用beanfactoryPostProcessors
                    invokeBeanFactoryPostProcessors(beanFactory);

                    // Register bean processors that intercept bean creation.
                    //注册bean processors 用于拦截bean的创建
                    registerBeanPostProcessors(beanFactory);

                    // Initialize message source for this context.
                    //初始化容器消息源
                    initMessageSource();

                    // Initialize event multicaster for this context.
                    //初始化事件广播者
                    initApplicationEventMulticaster();

                    // Initialize other special beans in specific context subclasses.
                    //初始化子容器其它特定beans 
                    onRefresh();

                    // Check for listener beans and register them.
                    //注册监听者
                    registerListeners();

                    // Instantiate all remaining (non-lazy-init) singletons.
                    //实例化所有拥有非懒加载的单例
                    finishBeanFactoryInitialization(beanFactory);

                    // Last step: publish corresponding event.
                    //最后一步,发布对应的事件
                    finishRefresh();
                }
        //省略一些代码
            }
        }

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

        @Override
        protected final void refreshBeanFactory() throws BeansException {
            if (hasBeanFactory()) {
                destroyBeans();
                closeBeanFactory();
            }
            try {
                //创建beafactory
                DefaultListableBeanFactory beanFactory = createBeanFactory();
                beanFactory.setSerializationId(getId());
                customizeBeanFactory(beanFactory);
                //加载beandefinitions 
                loadBeanDefinitions(beanFactory);
                synchronized (this.beanFactoryMonitor) {
                    this.beanFactory = beanFactory;
                }
            }
            catch (IOException ex) {
                throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
            }
        }
        @Override
        protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
            // Create a new XmlBeanDefinitionReader for the given BeanFactory.
            //创建xml beandefinition reader
            XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

            // Configure the bean definition reader with this context's
            // resource loading environment.
            beanDefinitionReader.setEnvironment(this.getEnvironment());
            beanDefinitionReader.setResourceLoader(this);
            beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

            // Allow a subclass to provide custom initialization of the reader,
            // then proceed with actually loading the bean definitions.
            initBeanDefinitionReader(beanDefinitionReader);
            //通过xml reader 读取xml配置文件 
            loadBeanDefinitions(beanDefinitionReader);
        }
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
            Resource[] configResources = getConfigResources();
            if (configResources != null) {
                reader.loadBeanDefinitions(configResources);
            }
            //获得所有配置资源
            String[] configLocations = getConfigLocations();
            if (configLocations != null) {
                //正式通过xmlreader解释xml 配置,并把解释到的beandedinition
                //注册到beanfactory里,接下来就是beans模块已讲过的了
                reader.loadBeanDefinitions(configLocations);
            }
        }

3 预实例化beanfactory里单例对象

接下要分析如何把上面得到的beandefinitions 进行实例化

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
            // Initialize conversion service for this context.
            if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                    beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        //省略一大波代码
        // Instantiate all remaining (non-lazy-init) singletons.
        //预实例化单例,
            beanFactory.preInstantiateSingletons();
    }

获取beanfactory里所有beanNames进行实例化

@Override
    public void preInstantiateSingletons() throws BeansException {
            //获得所有beanNames 
            List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

            //逐个遍历,实例化预加载单例对象
            for (String beanName : beanNames) {
                RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                    //判断要创建的实例是否为FactoryBean
                    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 {
                        //开始他建实例,这块是beans模块内容,不再重述了
                        getBean(beanName);
                    }
                }
            }
            //这里省略一些代码
    }

来源:[]()

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> spring 源码-context(一)

相关推荐