欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

IMPORT_ELEMENT)) { importBeanDefiniti 劳务派遣信息管理系统 onResource

点击: 次  来源:宝鼎软件 时间:2017-06-01

原文出处: 五月的仓颉

代码进口

之前写文章城市啰烦琐嗦一大堆再开始,进入【Spring源码阐明】这个板块就直接切入正题了。

许多伴侣大概想看Spring源码,可是不知道该当如何入手去看,这个可以领略:Java开拓者凡是从事的都是Java Web的事情,对付措施员来说,一个Web项目用到Spring,只是设置一下设置文件罢了,Spring的加载进程相对是不太透明的,不太好去找加载的代码进口。

下面有很简朴的一段代码可以作为Spring代码加载的进口:

ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
ac.getBean(XXX.class);

ClassPathXmlApplicationContext用于加载CLASSPATH下的Spring设置文件,软件开发,可以看到,第二行就已经可以获取到Bean的实例了,那么一定第一行就已经完成了对所有Bean实例的加载,因此可以通过ClassPathXmlApplicationContext作为进口。为了后头便于代码阅读,先给出一下ClassPathXmlApplicationContext这个类的担任干系: IMPORT_ELEMENT)) { importBeanDefiniti 劳务调派信息打点系统 onResource(ele); } else if (delegate.nodeNameEquals(ele

大抵的担任干系是如上图所示的,由于版面的干系,没有继承画下去了,左下角的ApplicationContext该当尚有一层担任干系,较量要害的一点是它是BeanFactory的子接口。

最后声明一下,本文利用的Spring版本为3.0.7,较量老,利用这个版本纯粹是因为公司利用罢了。

ClassPathXmlApplicationContext结构函数

看下ClassPathXmlApplicationContext的结构函数:

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

    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

从第二段代码看,总共就做了三件事:

1、super(parent)

没什么太大的浸染,配置一下父级ApplicationContext,这里是null

2、setConfigLocations(configLocations)

代码就不贴了,一看就知道,内里做了两件工作:

(1)将指定的Spring设置文件的路径存储到当地

(2)理会Spring设置文件路径中的${PlaceHolder}占位符,替换为系统变量中PlaceHolder对应的Value值,System自己就自带一些系统变量好比class.path、os.name、user.dir等,也可以通过System.setProperty()要领配置本身需要的系统变量

3、refresh()

这个就是整个Spring Bean加载的焦点了,它是ClassPathXmlApplicationContext的父类AbstractApplicationContext的一个要领,顾名思义,用于刷新整个Spring上下文信息,界说了整个Spring上下文加载的流程。

refresh要领

上面已经说了,refresh()要领是整个Spring Bean加载的焦点,因此看一下整个refresh()要领的界说:

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

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

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }
        }
    }

每个子要领的成果之后一点一点再阐明,首先refresh()要领有几点是值得我们进修的:

1、要领是加锁的,这么做的原因是制止多线程同时刷新Spring上下文

2、尽量加锁可以看到是针对整个要领体的,可是没有在要领前加synchronized要害字,而利用了工具锁startUpShutdownMonitor,这样做有两个长处: