Spring源码解析beanfactoryWord格式文档下载.docx
《Spring源码解析beanfactoryWord格式文档下载.docx》由会员分享,可在线阅读,更多相关《Spring源码解析beanfactoryWord格式文档下载.docx(42页珍藏版)》请在冰豆网上搜索。
returntestStr;
publicvoidsetTestStr(StringtestStr){
<
?
xmlversion="
1.0"
encoding="
UTF-8"
>
beansxmlns="
http:
//www.springframework.org/schema/beans"
xmlns:
xsi="
//www.w3.org/2001/XMLSchema-instance"
context="
//www.springframework.org/schema/context"
xsi:
schemaLocation="
//www.springframework.org/schema/beans
<
beanname="
class="
qbb.spring.bean.MyBean"
>
/bean>
/beans>
uml类图
上次看的时候就画过这个图,这次做了细化和调整。
XmlBeanFactory继承关系
AliasRegistry定义对Alias的简单增删改等操作;
SimpleAliasRegistry使用currenthashmap作为缓存,并对接口AliasRegisty进行实现;
SingletonBeanRegistry定义对单例的获取及获取;
DefaultSingletonBeanRegistry是SingletonBeanRegistry的实现;
FactoryBeanRegistrySupport在DefaultSingletonBeanRegistry基础上,增加对FactorBean的特殊处理功能;
BeanFactory定义获取bean及bean的各种属性;
HierarchicalBeanFactory继承BeanFactory,增加对parentFactory的支持;
ConfigurableBeanFactory提供配置各种factory的方法;
ListableBeanFactory根据不同条件获取bean的配置清单;
AutowireCapableBeanFactory提供创建bean,自动注入,初始化已经应用bean后的处理器;
AbstractBeanFactory综合FactoryBeanRegistrySupport和ConfigurableBeanFactory功能;
ConfigurableListableBeanFactory是BeanFactory的配置清单,指定忽略类型和接口等;
AbstractAutowireCapableBeanFactory综合AbstractBeanFactory并对接口AutowireCapalbeBeanFactory的实现;
BeanDefinitionRegistry定义对BeanDefinition的curd操作;
DefaultListableBeanFactory综合所有功能,主要是bean注册后的处理;
XmlBeanFactory对DefaultListableBeanFactory类进行了扩展,主要是从xml文档读取BeanDefinition,对于注册以及获取Bean都是从父类DefaultLisstableBean继承的方法去实现,与父类的不同就是增加了XmlBeanDefinitionReader类型的reader属性,在XmlBeanFactory中主要使用reader属性对资源文件进行读取和注册;
XmlBeanDefinitionReader
EnvironmentCapable定义获取Environment的方法;
BeanDefinitionReader主要定义资源文件读取并转化为BeanDefinition的各种功能;
AbstractBeanDefinitionReader对接口的实现;
ResourceLoader资源加载器,根据给定的资源文件地址返回对应的Resource;
DocumentLoader资源文件转化为Document的功能;
BeanDefinitionDocumentReader读取Document并注册BeanFinition的功能;
BeanDefinitionParserDelegate定义解析element的各种方法;
BeanDefinition
BeanDefinition配置文件bean元素在容器的内部表现形式;
ChildBeanDefinition父子bean中的子bean;
GenericBeanDefinition2.5后加入,一站式的服务类;
RootBeanDefinition对应一般性的bean元素标签,父子bean中的父bean可以用此表示,没有父bean的bean也使用来表示;
xml解析beanDefinition
BeanFactoryctx=newXmlBeanFactory(newClassPathResource("
资源文件抽象
newClassPathResource("
)
spring将外部的资源封装成内部使用Resource,可以从文件,class,jar,还有context上下文:
我这里使用ClassPathResource加载spring文件,当然也可以使用FileSystemResource从文件系统路径加载。
loadBeanDefinition
newXmlBeanFactory(newClassPathResource("
调用XmlBeanFactory构造
//XmlBeanFactory
publicXmlBeanFactory(Resourceresource)throwsBeansException{
this(resource,null);
publicXmlBeanFactory(Resourceresource,BeanFactoryparentBeanFactory)throwsBeansException{
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
在条用super的时候会设置parentBeanFactory,好像只要mvc的时候才看到设置,其他地方基本没用到。
//AbstractAutowireCapableBeanFactory
publicAbstractAutowireCapableBeanFactory(BeanFactoryparentBeanFactory){
this();
setParentBeanFactory(parentBeanFactory);
publicAbstractAutowireCapableBeanFactory(){
super();
//忽略一些依赖,在getbean的时候,在实例化属性填充后,会检查设置这些依赖关系,
//然后再去调用实现InitializingBean的afterPropertiesSet方法和自定义的Init-Method
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
//AbstractBeanFactory
publicvoidsetParentBeanFactory(BeanFactoryparentBeanFactory){
if(this.parentBeanFactory!
=null&
&
this.parentBeanFactory!
=parentBeanFactory){
thrownewIllegalStateException("
AlreadyassociatedwithparentBeanFactory:
"
+this.parentBeanFactory);
this.parentBeanFactory=parentBeanFactory;
在这些完了后会调用
//xmlbeanfactory
this.reader.loadBeanDefinitions(resource);
XmlBeanFactory使用XmlBeanDefinitionReader来解析和注册bean定义。
//XmlBeanDefinitionReader
publicintloadBeanDefinitions(Resourceresource)throwsBeanDefinitionStoreException{
//EncodedResource做了编码处理,getReader时如果有编码就使用,没有就不适用
returnloadBeanDefinitions(newEncodedResource(resource));
publicintloadBeanDefinitions(EncodedResourceencodedResource)throwsBeanDefinitionStoreException{
...
try{
InputStreaminputStream=encodedResource.getResource().getInputStream();
InputSourceinputSource=newInputSource(inputStream);
if(encodedResource.getEncoding()!
=null){
inputSource.setEncoding(encodedResource.getEncoding());
returndoLoadBeanDefinitions(inputSource,encodedResource.getResource());
finally{
inputStream.close();
看了下,spring中习惯doXXX来表示真正干活的代码,XXX来做主流程控制。
自己写代码的时候有时流程会不清晰,会乱,后来还是从spring里面学会这招,先提炼主流程,然后再分配。
protectedintdoLoadBeanDefinitions(InputSourceinputSource,Resourceresource)
throwsBeanDefinitionStoreException{
intvalidationMode=getValidationModeForResource(resource);
Documentdoc=this.documentLoader.loadDocument(
inputSource,getEntityResolver(),this.errorHandler,validationMode,isNamespaceAware());
returnregisterBeanDefinitions(doc,resource);
xml文件校验和解析
intvalidationMode=getValidationModeForResource(resource);
xml文档的2种校验方式:
DTD和XSD,通过getValidationModeForResource来获取,DTD的会包含DOCTYPE,所以通过解析这个是否存在判断。
校验过后就是通过DefaultDocumentLoader将xml文件解析Document,xml文件解析一般就是SAX、Dom、jdom,dom4j。
registerBeanDefinitions
publicintregisterBeanDefinitions(Documentdoc,Resourceresource)throwsBeanDefinitionStoreException{
//将DefaultBeanDefinitionDocumentReader转为BeanDefinitionDocumentReader
BeanDefinitionDocumentReaderdocumentReader=createBeanDefinitionDocumentReader();
//this.getEnvironment()获取到的是StandardEnvironment,可以用来获取系统变量和环境变量
documentReader.setEnvironment(this.getEnvironment());
intcountBefore=getRegistry().getBeanDefinitionCount();
//使用DefaultBeanDefinitionDocumentReader解析document
documentReader.registerBeanDefinitions(doc,createReaderContext(resource));
returngetRegistry().getBeanDefinitionCount()-countBefore;
protectedXmlReaderContextcreateReaderContext(Resourceresource){
if(this.namespaceHandlerResolver==null){
//DefaultNamespaceHandlerResolver,主要用来获取标签的解析,
//特别是自定义标签的解析,后面单独讲下这个,里面最重要的方法NamespaceHandlerresolve(StringnamespaceUri)
this.namespaceHandlerResolver=createDefaultNamespaceHandlerResolver();
returnnewXmlReaderContext(resource,this.problemReporter,this.eventListener,
this.sourceExtractor,this,this.namespaceHandlerResolver);
最终还是委托DefaultBeanDefinitionDocumentReader来解析Document。
//DefaultBeanDefinitionDocumentReader
publicvoidregisterBeanDefinitions(Documentdoc,XmlReaderContextreaderContext){
this.readerContext=readerContext;
logger.debug("
Loadingbeandefinitions"
Elementroot=doc.getDocumentElement();
doRegisterBeanDefinitions(root);
protectedvoiddoRegisterBeanDefinitions(Elementroot){
//profile属性,类似maven-p,可以定义不同环境下的bean定义,配合环境变量spring.profiles.active使用
StringprofileSpec=root.getAttribute(PROFILE_ATTRIBUTE);
if(StringUtils.hasText(profileSpec)){
Assert.state(this.environment!
=null,"
environmentpropertymustnotbenull"
String[]specifiedProfiles=StringUtils.tokenizeToStringArray(profileSpec,BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if(!
this.environment.acceptsProfiles(specifiedProfiles)){
return;
//anynested<
beans>
elementswillcauserecursioninthismethod.In
//ordertopropagateandpreserve<
default-*attributescorrectly,
//keeptrackofthecurrent(parent)delegate,whichmaybenull.Create
//thenew(child)delegatewithareferencetotheparentforfallbackpurposes,
//thenultimatelyresetthis.delegatebacktoitsoriginal(parent)reference.
//thisbehavioremulatesastackofdelegateswithoutactuallynecessitatingone.
BeanDefinitionParserDelegateparent=this.delegate;
//BeanDefinitionParserDelegate
this.delegate=createHelper(readerContext,root,parent);
preProcessXml(root);
//子类实现
parseBeanDefinitions(root,this.delegate);
postProcessXml(root);
this.delegate=parent;
protectedBeanDefinitionParserDelegatecreateHelper(XmlReaderContextreaderContext,Elementroot,BeanDefinitionParserDelegateparentDelegate){
BeanDefinitionParserDelegatedelegate=newBeanDefinitionParserDelegate(readerContext,environment);
delegate.initDefaults(root,parentDelegate);
returndelegate;
//BeanDefinitionParserDelegate
publicvoidinitDefaults(Elementroot,BeanDefinitionParserDelegateparent){
populateDefaults(this.defaults,(parent!
=null?
parent.defaults:
null),root);
this.readerContext.fireDefaultsRegistered(this.defaults);
//收集一些默认属性
protectedvoidpopulateDefaults(DocumentDefaultsDefinitiondefaults,DocumentDefaultsDefinitionparentDefaults,Elementroot){
StringlazyInit=root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
if(DEFAULT_VALUE.equals(lazyInit)){
lazyInit=parentDefaults!
parentDefaults.getLazyInit():
FALSE_VALUE;
defaults.setLazyInit(lazyInit);
Stringmerge=root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
if(DEFAULT_VALUE.equals(merge)){
merge=parentDefaults!
parentDefaults.getMerge():
defaults.setMerge(merge);
Stringautowire=root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
if(DEFAULT_VALUE.equals(au