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的时候,每次都会被新初始化的
通过日志的内容,梳理一下大概初始化逻辑
spring framework 4 源码阅读(2)---从ClassPathXmlApplicationContext开始的更多相关文章
- spring framework 4 源码阅读(1) --- 前期准备
在开始看代码之前,需要做的第一件事是下载代码. 在这里:https://github.com/spring-projects/spring-framework 下载完成了发现使用gradle做的源代码 ...
- spring framework 4 源码阅读
前面写了几篇spring 的介绍文章,感觉与主题不是很切合.重新整理下思路,从更容易理解的角度来写下文章. spring 的骨架 spring 的骨架,也是spring 的核心包.主要包含三个内容 1 ...
- Spring 注册BeanPostProcessor 源码阅读
回顾上一篇博客中,在AbstractApplicationContext这个抽象类中,Spring使用invokeBeanFactoryPostProcessors(beanFactory);执行Be ...
- spring framework项目源码github托管地址
方法一:直接下载,github托管地址:http://repo.spring.io/simple/libs-release-local/org/springframework/spring/ 方法二: ...
- (转) Spring源码阅读 之 Spring整体架构
标签(空格分隔): Spring 声明:本文系转载,原地地址:spring framework 4 源码阅读 Spring骨架 Spring的骨架,也是Spring的核心包.主要包含三个内容 cont ...
- Spring源码阅读笔记
前言 作为一个Java开发者,工作了几年后,越发觉力有点不从心了,技术的世界实在是太过于辽阔了,接触的东西越多,越感到前所未有的恐慌. 每天捣鼓这个捣鼓那个,结果回过头来,才发现这个也不通,那个也不精 ...
- Spring源码阅读系列总结
最近一段时间,粗略的查看了一下Spring源码,对Spring的两大核心和Spring的组件有了更深入的了解.同时在学习Spring源码时,得了解一些设计模式,不然阅读源码还是有一定难度的,所以一些重 ...
- Bean实例化(Spring源码阅读)-我们到底能走多远系列(33)
我们到底能走多远系列(33) 扯淡: 各位: 命运就算颠沛流离 命运就算曲折离奇 命运就算恐吓着你做人没趣味 别流泪 心酸 更不应舍弃 ... 主题: Spring源码阅读还在继 ...
- 初始化IoC容器(Spring源码阅读)
初始化IoC容器(Spring源码阅读) 我们到底能走多远系列(31) 扯淡: 有个问题一直想问:各位你们的工资剩下来会怎么处理?已婚的,我知道工资永远都是不够的.未婚的你们,你们是怎么分配工资的? ...
随机推荐
- [LeetCode] 147. Insertion Sort List 解题思路
Sort a linked list using insertion sort. 问题:实现单向链表的插入排序. 这是比较常规的一个算法题目. 从左往右扫列表,每次将指针的下一个元素插入前面已排好序的 ...
- Contest - 2014 SWJTU ACM 手速测试赛(2014.10.31)
题目列表: 2146 Problem A [手速]阔绰的Dim 2147 Problem B [手速]颓废的Dim 2148 Problem C [手速]我的滑板鞋 2149 Problem D [手 ...
- BeanstalkClient学习
针对BeanstalkClient-1.4.6.jar 生产者 示例代码: package com.lky.test; import java.io.UnsupportedEncodingExcept ...
- css的小demo
demo1 一个高度随宽度变化的正方形 (缩小屏幕试试) 原理:margin和padding如果是用百分比设置,则是以父元素的宽度的百分比设置的. .Square{ display: inline ...
- android中发送邮件
在移动互联网时代,手机邮件已不是什么新鲜事了,我们可以使用内置的Gmail引擎来发送邮件,也可以使用SMTP来发送邮件,下面用一个简单示例来演示邮件的发送,包括单方发送邮件.多方发送邮件以及抄送邮件, ...
- 2014ACMICPC亚洲区域赛牡丹江现场赛之旅
下午就要坐卧铺赶回北京了.闲来无事.写个总结,给以后的自己看. 因为孔神要保研面试,所以仅仅有我们队里三个人上路. 我们是周五坐的十二点出发的卧铺,一路上不算无聊.恰巧邻床是北航的神犇.于是下午和北航 ...
- Android:Service的非绑定式的创建和生命周期
Android的Service若使用非绑定式的创建,则创建后将无法再与它取得联系.即无法传递消息參数等: 所以假设希望创建后仍然与其存在联系,那么能够參考我的前几篇博客<Android:Serv ...
- Win32函数Sleep的精度测试
用了三种方法,第一种使用高精度性能计数器:第二种是使用多媒体定时器,另一种是<Windows图形编程>里提供的CPU周期来获取.推荐第一种方式测量: 先看第一种: #include < ...
- C#位移运算符
代码如下: /// <summary> /// 位移运算符"<<"左位移运算符,">>"右位移运算符 /// 在进行位移运算 ...
- Messager( 消息窗口) 组件
一. 加载方式消息窗口提供了不同的消息框风格,包含 alert(警告框).confirm(确认框).prompt(提示框).progress(进度框)等.所有消息框都是异步的,用户可以在交互消息之后使 ...