zoukankan      html  css  js  c++  java
  • spring framework 4 源代码阅读(2)---从ClassPathXmlApplicationContext開始

    Application初始化日志

    15:23:12.790 [main] DEBUG o.s.core.env.StandardEnvironment - Adding [systemProperties] PropertySource with lowest search precedence
    15:23:12.797 [main] DEBUG o.s.core.env.StandardEnvironment - Adding [systemEnvironment] PropertySource with lowest search precedence
    15:23:12.797 [main] DEBUG o.s.core.env.StandardEnvironment - Initialized StandardEnvironment with PropertySources [systemProperties,systemEnvironment]
    //初始化Environment
    15:23:12.803 [main] INFO  o.s.c.s.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@480a6370: startup date [Mon Aug 25 15:23:12 CST 2014]; root of context hierarchy
    15:23:12.861 [main] DEBUG o.s.core.env.StandardEnvironment - Adding [systemProperties] PropertySource with lowest search precedence
    15:23:12.862 [main] DEBUG o.s.core.env.StandardEnvironment - Adding [systemEnvironment] PropertySource with lowest search precedence
    15:23:12.862 [main] DEBUG o.s.core.env.StandardEnvironment - Initialized StandardEnvironment with PropertySources [systemProperties,systemEnvironment]
    //读取XML
    15:23:12.880 [main] INFO  o.s.b.f.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [simpleContext.xml]
    15:23:12.885 [main] DEBUG o.s.b.f.xml.DefaultDocumentLoader - Using JAXP provider [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl]
    15:23:12.928 [main] DEBUG o.s.b.factory.xml.BeansDtdResolver - Found beans DTD [http://www.springframework.org/dtd/spring-beans-2.0.dtd] in classpath: spring-beans-2.0.dtd
    //读取BeanDefinition
    15:23:12.953 [main] DEBUG o.s.b.f.x.DefaultBeanDefinitionDocumentReader - Loading bean definitions
    //解析XML
    15:23:12.971 [main] DEBUG o.s.b.f.x.BeanDefinitionParserDelegate - No XML 'id' specified - using 'simpleBean' as bean name and [] as aliases
    15:23:12.986 [main] DEBUG o.s.b.f.x.BeanDefinitionParserDelegate - No XML 'id' specified - using 'anotherBean' as bean name and [] as aliases
    15:23:12.986 [main] DEBUG o.s.b.f.xml.XmlBeanDefinitionReader - Loaded 3 bean definitions from location pattern [simpleContext.xml]
    //将获取到的BeanDefined设置到BeanFactory中
    15:23:12.987 [main] DEBUG o.s.c.s.ClassPathXmlApplicationContext - Bean factory for org.springframework.context.support.ClassPathXmlApplicationContext@480a6370: org.springframework.beans.factory.support.DefaultListableBeanFactory@74bdaaa: defining beans [simpleBean,property,anotherBean]; root of factory hierarchy
    //初始化MessageSource,I18N中使用
    15:23:13.025 [main] DEBUG o.s.c.s.ClassPathXmlApplicationContext - Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource@6f526c5f]
    //application事件中心
    15:23:13.029 [main] DEBUG o.s.c.s.ClassPathXmlApplicationContext - Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicationEventMulticaster@5629fbc9]

    一些bean的初始化

    一个简单的bean,里面有个属性property,以及test方法和须要进行属性注入的setProperty
    /**
     * 主要的bean方便測试
     * Created by zhangya on 2014/8/13.
     */
    public class SimpleBean
    {
    	private static final Logger LOGGER = LoggerFactory.getLogger(SimpleBean.class);
    	private SimpleBeanProperty property;
    
    	/**
    	 * 简单測试方法
    	 */
    	public void test()
    	{
    		LOGGER.info("SimpleBean is loading.");
    		property.propertyTest();
    	}
    
    	/**
    	 * 设置属性 property
    	 * <p>记录日志
    	 * @param property
    	 */
    	public void setProperty(SimpleBeanProperty property)
    	{
    		LOGGER.info("Property is setting.");
    		this.property = property;
    	}
    }

    作为属性赋值的bean,里面包括初始化方法

    /**
     * 作为属性初始化的bean
     * Created by zhangya on 2014/8/13.
     */
    public class SimpleBeanProperty
    {
    	private static final Logger LOGGER = LoggerFactory.getLogger(SimpleBeanProperty.class);
    	private String simpleVariable = "test567";
    	public SimpleBeanProperty()
    	{
    		LOGGER.info("SimpleBeanProperty is loading.");
    	}
    
    	/**
    	 * property的test方法
    	 */
    	public void propertyTest()
    	{
    		LOGGER.info("propertyTest method is invoking.{}",this);
    	}
    
    	/**
    	 * 设置变量
    	 * @param simpleVariable
    	 */
    	public void setSimpleVariable(String simpleVariable)
    	{
    		this.simpleVariable = simpleVariable;
    	}
    
    	/**
    	 * 获取变量的值
    	 * @return 变量的值
    	 */
    	public String getSimpleVariable()
    	{
    		return simpleVariable;
    	}
    
    	@Override
    	public String toString()
    	{
    		return "SimpleBeanProperty{" +
    				"simpleVariable='" + simpleVariable + ''' +
    				'}';
    	}
    }

    另外一个

    /**
     * 用于初始化的另外一个bean
     * @author zhangya
     * @category com.letume.spring.study.init
     * @since 2014/8/24
     */
    public class SimpleAnotherBean
    {
    	private static final Logger LOGGER = LoggerFactory.getLogger(SimpleBeanProperty.class);
    	private String simpleVariable = "test123";
    
    	public SimpleAnotherBean()
    	{
    		LOGGER.info("SimpleAnotherBean is loading.");
    	}
    
    	/**
    	 * property的test方法
    	 */
    	public void test()
    	{
    		LOGGER.info("test method is invoking.{}",this);
    	}
    
    	/**
    	 * 设置变量
    	 * @param simpleVariable
    	 */
    	public void setSimpleVariable(String simpleVariable)
    	{
    		this.simpleVariable = simpleVariable;
    	}
    
    	@Override
    	public String toString()
    	{
    		return "SimpleAnotherBean{" +
    				"simpleVariable='" + simpleVariable + ''' +
    				'}';
    	}
    }

    simpleContext.xml applicationContext的配置文件,这里使用xml形式对bean进行配置

    <?

    xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <bean name="simpleBean" class="com.letume.spring.study.init.SimpleBean"> <property name="property"><ref local="property"/> </property> </bean> <bean id="property" name="property" class="com.letume.spring.study.init.SimpleBeanProperty" scope="prototype"/> <bean name="anotherBean" class="com.letume.spring.study.init.SimpleAnotherBean" scope="prototype"/> </beans>

    以下是main函数,

    例1 普通的bean初始化调用过程

    /**
     * 简单的spring类载入的方法
     * <pre>
     * ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(PATH+RESOURCE_CONTEXT);
     * SimpleBean simpleBean = context.getBean(SimpleBean.class)
     * simpleLoaderSimpleBean.test();
     * </pre>
     * Created by mitchz on 2014/8/13.
     */
    public class SimpleInit
    {
    
    	private static final String PATH = "";
    	private static final String RESOURCE_CONTEXT = "simpleContext.xml";
    
    	public static void main(String[] args) throws InterruptedException
    	{
    		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
    				PATH + RESOURCE_CONTEXT);
    		//获取simpleBean
    		SimpleBean simpleBean = context
    				.getBean("simpleBean", SimpleBean.class);
    		simpleBean.test();
    		//context.registerShutdownHook();
    	}
    }

    看下日志:
    ---运行单例的初始化(为什么会使用单例)
    14:36:48.766 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@29d8a2c5: defining beans [simpleBean,property,anotherBean]; root of factory hierarchy
    14:36:48.767 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'simpleBean'
    ---创建bean实例
    14:36:48.767 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'simpleBean'
    14:36:48.786 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'simpleBean' to allow for resolving potential circular references
    ---创建属性的实例
    14:36:48.799 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'property'
    14:36:48.799 [main] INFO  c.l.s.study.init.SimpleBeanProperty - SimpleBeanProperty is loading.
    14:36:48.799 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'property'
    ---赋值
    14:36:48.838 [main] INFO  c.l.spring.study.init.SimpleBean - Property is setting.
    14:36:48.840 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'simpleBean'
    
    
    ....
    
    
    ---getBean的方法运行时,则直接从cache中取。之前初始化的实例
    14:36:48.847 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'simpleBean'
    14:36:48.847 [main] INFO  c.l.spring.study.init.SimpleBean - SimpleBean is loading.SimpleBean{property=SimpleBeanProperty{simpleVariable='test567'}}
    14:36:48.849 [main] INFO  c.l.s.study.init.SimpleBeanProperty - propertyTest method is invoking.SimpleBeanProperty{simpleVariable='test567'}
    

    从日志中能够看出bean在没有设置scope的时候,默认值为singletone的。另外即使属性类是protetype的时候,也会在父bean初始化将其填充。

    不会在调用父bean的时候,又一次初始化属性所关联的bean。具体见例2


    例2。在运行过程中,添加属性改动,咱们再来运行下看看

    		//改动property bean实例中的变量simpleVariable
    		simpleBean.getProperty().setSimpleVariable("aaaaa");
    		//又一次获取simpleBean实例
    		simpleBean = context
    				.getBean("simpleBean", SimpleBean.class);
    		//再次运行test方法
    		simpleBean.test();
    看下新增的日志:
    15:14:58.447 [main] INFO  c.l.spring.study.init.SimpleBean - SimpleBean is loading.SimpleBean{property=SimpleBeanProperty{simpleVariable='aaaaa'}}
    15:14:58.447 [main] INFO  c.l.s.study.init.SimpleBeanProperty - propertyTest method is invoking.SimpleBeanProperty{simpleVariable='aaaaa'}
    看来咱们之前的推測是对的,

    第一、bean的scope默觉得SingleTone的

    第二、bean的lazyInit为false的

    第三、即使属性为prototype也不会再父bean为SingleTone的时又一次初始化


    例3、再添加两行

    		//获取property实例
    		SimpleBeanProperty property = context
    				.getBean("property", SimpleBeanProperty.class);
    		//測试propertyTest方法
    		property.propertyTest();

    再看下运行后新增的日志:
    15:19:10.331 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'property'
    15:19:10.331 [main] INFO  c.l.s.study.init.SimpleBeanProperty - SimpleBeanProperty is loading.
    15:19:10.331 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'property'
    15:19:10.331 [main] INFO  c.l.s.study.init.SimpleBeanProperty - propertyTest method is invoking.SimpleBeanProperty{simpleVariable='test567'}
    因为property的bean因为是prototype的,所以被又一次初始化了。


    例4、再添加四行:

    		//获取anotherBean实例
    		SimpleAnotherBean anotherBean = context
    				.getBean("anotherBean", SimpleAnotherBean.class);
    		anotherBean.test();
    		//设置变量的值
    		anotherBean.setSimpleVariable("bbbbb");
    		//又一次获取anotherBean实例
    		anotherBean = context
    				.getBean("anotherBean", SimpleAnotherBean.class);
    		anotherBean.test();

    大家在看下运行日志:
    15:23:13.130 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'anotherBean'
    15:23:13.130 [main] INFO  c.l.s.study.init.SimpleBeanProperty - SimpleAnotherBean is loading.
    15:23:13.130 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'anotherBean'
    15:23:13.130 [main] INFO  c.l.s.study.init.SimpleBeanProperty - test method is invoking.SimpleAnotherBean{simpleVariable='test123'}
    15:23:13.131 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'anotherBean'
    15:23:13.131 [main] INFO  c.l.s.study.init.SimpleBeanProperty - SimpleAnotherBean is loading.
    15:23:13.131 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'anotherBean'
    15:23:13.131 [main] INFO  c.l.s.study.init.SimpleBeanProperty - test method is invoking.SimpleAnotherBean{simpleVariable='test123'}
    bean为prototype的时候。每次都会被新初始化的

    通过日志的内容,梳理一下大概初始化逻辑




    能够看出主要针对beans context 还有core包。


    详细怎么相互协作的。下一篇会进一步介绍。

    
       
    
  • 相关阅读:
    如何查看openssl支持的所有TLS/SSL版本
    讲故事,学(AHK)设计模式—观察者模式
    React Hooks 详解 【近 1W 字】+ 项目实战
    为什么要在函数组件中使用React.memo?
    js防抖函数
    JS 深度优先遍历与广度优先遍历 实现查找
    你不知道的 requestIdleCallback
    RE:ゼロから始める文化課生活
    开学考小记 & 新生活的开始
    JS中:数组和对象的区别,以及遍历数组和遍历对象的区别
  • 原文地址:https://www.cnblogs.com/jhcelue/p/6753151.html
Copyright © 2011-2022 走看看