java的d,java_D

文章参考来自:https://www.cnblogs.com/ITtan...

文章代码来自 spring-boot 1.4.1 Release版本

Spring IoC容器对Bean定义资源的载入是从refresh()函数开始的,refresh()是一个模板方法,refresh()方法的作用是:在创建IoC容器前,如果已经有容器存在,则需要把已有的容器销毁和关闭,以保证在refresh之后使用的是新建立起来的IoC容器。refresh的作用类似于对IoC容器的重启,在新建立好的容器中对容器进行初始化,对Bean定义资源进行载入public void refresh() throws BeansException, IllegalStateException {

Object var1 = this.startupShutdownMonitor;

synchronized(this.startupShutdownMonitor) {

//调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识

this.prepareRefresh();

//告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从

//子类的refreshBeanFactory()方法启动

//这个bean的载入过程 包括对xml的解析和加载为BeanDefinitions 都是从this.obtainFreshBeanFactory()这里进入

ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

/*这之后的代码都是注册容器的信息源和生命周期事件*/

//为BeanFactory配置容器特性,例如类加载器、事件处理器等

this.prepareBeanFactory(beanFactory);

try {

//为容器的某些子类指定特殊的BeanPost事件处理器

this.postProcessBeanFactory(beanFactory);

//调用所有注册的BeanFactoryPostProcessor的Bean

this.invokeBeanFactoryPostProcessors(beanFactory);

//为BeanFactory注册BeanPost事件处理器.

//BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件

this.registerBeanPostProcessors(beanFactory);

//初始化信息源,和国际化相关.

this.initMessageSource();

//初始化容器事件传播器.

this.initApplicationEventMulticaster();

//调用子类的某些特殊Bean初始化方法

this.onRefresh();

//为事件传播器注册事件监听器.

this.registerListeners();

//初始化所有剩余的单态Bean.

this.finishBeanFactoryInitialization(beanFactory);

//初始化容器的生命周期事件处理器,并发布容器的生命周期事件

this.finishRefresh();

} catch (BeansException var9) {

if (this.logger.isWarnEnabled()) {

this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);

}

//销毁以创建的单态Bean

this.destroyBeans();

//取消refresh操作,重置容器的同步标识.

this.cancelRefresh(var9);

throw var9;

} finally {

this.resetCommonCaches();

}

}

}

AbstractRefreshableApplicationContext 类:

AbstractRefreshableApplicationContext中只定义了抽象的loadBeanDefinitions方法,容器真正调用的是其子类AbstractXmlApplicationContext对该方法的实现protected final void refreshBeanFactory() throws BeansException {

//如果已经创建了BeanFactory,则销毁并关闭BeanFactory

if (this.hasBeanFactory()) {

this.destroyBeans();

this.closeBeanFactory();

}

try {

//创建了一个IOC容器

DefaultListableBeanFactory beanFactory = this.createBeanFactory();

beanFactory.setSerializationId(this.getId());

/对IoC容器进行定制化,如设置启动参数,开启注解的自动装配等

this.customizeBeanFactory(beanFactory);

//调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器

this.loadBeanDefinitions(beanFactory);

Object var2 = this.beanFactoryMonitor;

synchronized(this.beanFactoryMonitor) {

this.beanFactory = beanFactory;

}

} catch (IOException var5) {

throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);

}

}

AbstractXmlApplicationContext 类:protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {

//创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容器使用该读取器读取Bean定义资源

XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

beanDefinitionReader.setEnvironment(this.getEnvironment());

//为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的

//祖先父类AbstractApplicationContext继承DefaultResourceLoader,因此,容器本身也是一个资源加载器

beanDefinitionReader.setResourceLoader(this);

//为Bean读取器设置SAX xml解析器

beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

//当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制

this.initBeanDefinitionReader(beanDefinitionReader);

//Bean读取器真正实现加载的方法

this.loadBeanDefinitions(beanDefinitionReader);

}

protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {

reader.setValidating(this.validating);

}

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {

Resource[] configResources = this.getConfigResources();

if (configResources != null) {

reader.loadBeanDefinitions(configResources);

}

String[] configLocations = this.getConfigLocations();

if (configLocations != null) {

reader.loadBeanDefinitions(configLocations);

}

}

@Nullable

protected Resource[] getConfigResources() {

return null;

}

在其抽象父类AbstractBeanDefinitionReader中定义了载入过程public int loadBeanDefinitions(String location, @Nullable Set actualResources) throws BeanDefinitionStoreException {

//获取resourceLoader

ResourceLoader resourceLoader = this.getResourceLoader();

if (resourceLoader == null) {

throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");

} else {

int loadCount;

if (!(resourceLoader instanceof ResourcePatternResolver)) {

//将指定位置的Bean定义资源文件解析为Spring IoC容器封装的资源

//加载多个指定位置的Bean定义资源文件 完成具体的资源定位的工作

Resource resource = resourceLoader.getResource(location);

//加载资源 开始我们的第二步操作 转换为BeanDefinition对象

loadCount = this.loadBeanDefinitions((Resource)resource);

if (actualResources != null) {

actualResources.add(resource);

}

if (this.logger.isDebugEnabled()) {

this.logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");

}

return loadCount;

} else {

try {

//将指定位置的Bean定义资源文件解析为Spring IoC容器封装的资源

//加载单个指定位置的Bean定义资源文件

Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);

//加载资源 开始我们的第二步操作 转换为BeanDefinition对象

loadCount = this.loadBeanDefinitions(resources);

if (actualResources != null) {

Resource[] var6 = resources;

int var7 = resources.length;

for(int var8 = 0; var8 < var7; ++var8) {

Resource resource = var6[var8];

actualResources.add(resource);

}

}

if (this.logger.isDebugEnabled()) {

this.logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");

}

return loadCount;

} catch (IOException var10) {

throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var10);

}

}

}

}

具体加载资源的方法

首先,调用资源加载器的获取资源方法resourceLoader.getResource(location),获取到要加载的资源。

其次,真正执行加载功能是其子类XmlBeanDefinitionReader的loadBeanDefinitions方法。

资源定位到这里就结束 最终返回的是一个Resource的对象来进行BeanDefinition的载入。在定位完成后,为BeanDefinition的载入创客I/O条件,

但是具体的载入还没有开始载入。public Resource getResource(String location) {

Assert.notNull(location, "Location must not be null");

Iterator var2 = this.protocolResolvers.iterator();

Resource resource;

do {

if (!var2.hasNext()) {

//处理/开头的定位

if (location.startsWith("/")) {

return this.getResourceByPath(location);

}

//带有classpath标识的Resource

if (location.startsWith("classpath:")) {

return new ClassPathResource(location.substring("classpath:".length()), this.getClassLoader());

}

try {

//处理URL标识的Resource定位

URL url = new URL(location);

return (Resource)(ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));

} catch (MalformedURLException var5) {

//如果不存classpath、Url、/标志的 就教给他处理

return this.getResourceByPath(location);

}

}

ProtocolResolver protocolResolver = (ProtocolResolver)var2.next();

resource = protocolResolver.resolve(location, this);

} while(resource == null);

return resource;

}protected Resource getResourceByPath(String path) {

if (path != null && path.startsWith("/")) {

path = path.substring(1);

}

//这里使用文件系统资源对象来定义bean 文件

return new FileSystemResource(path);

}

BeanDefinition的载入分成两部分,首先通过XML的解析器得到document对象,

但这些document对象没有按照spring的Bean规则进行解析。在完成XML解析后,才是按照Spring的Bean规则进行解析,这个解析的过程是在documentReader实现。public int loadBeanDefinitions(String location, @Nullable Set actualResources) throws BeanDefinitionStoreException {

//获取resourceLoader

ResourceLoader resourceLoader = this.getResourceLoader();

if (resourceLoader == null) {

throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");

} else {

int loadCount;

if (!(resourceLoader instanceof ResourcePatternResolver)) {

//将指定位置的Bean定义资源文件解析为Spring IoC容器封装的资源

//加载多个指定位置的Bean定义资源文件 完成具体的资源定位的工作

Resource resource = resourceLoader.getResource(location);

//加载资源 开始我们的第二步操作 转换为BeanDefinition对象

loadCount = this.loadBeanDefinitions((Resource)resource);

if (actualResources != null) {

actualResources.add(resource);

}

if (this.logger.isDebugEnabled()) {

this.logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");

}

return loadCount;

} else {

try {

//将指定位置的Bean定义资源文件解析为Spring IoC容器封装的资源

//加载单个指定位置的Bean定义资源文件

Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);

//加载资源 开始我们的第二步操作 转换为BeanDefinition对象

loadCount = this.loadBeanDefinitions(resources);

if (actualResources != null) {

Resource[] var6 = resources;

int var7 = resources.length;

for(int var8 = 0; var8 < var7; ++var8) {

Resource resource = var6[var8];

actualResources.add(resource);

}

}

if (this.logger.isDebugEnabled()) {

this.logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");

}

return loadCount;

} catch (IOException var10) {

throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var10);

}

}

}

}

xml文件转换为document对象 再解析BeanDefinition

这里是载入XML形式Bean定义资源文件方法public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {

Assert.notNull(encodedResource, "EncodedResource must not be null");

if(this.logger.isInfoEnabled()) {

this.logger.info("Loading XML bean definitions from " + encodedResource.getResource());

}

Set currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();

if(currentResources == null) {

currentResources = new HashSet(4);

this.resourcesCurrentlyBeingLoaded.set(currentResources);

}

if(!((Set)currentResources).add(encodedResource)) {

throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");

} else {

int var5;

try {

//将资源文件转为InputStream的IO流

InputStream inputStream = encodedResource.getResource().getInputStream();

try {

//从InputStream中得到XML的解析源

InputSource inputSource = new InputSource(inputStream);

if(encodedResource.getEncoding() != null) {

inputSource.setEncoding(encodedResource.getEncoding());

}

//这里是具体的读取过程

var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());

} finally {

//IO流的关闭

inputStream.close();

}

} catch (IOException var15) {

throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);

} finally {

((Set)currentResources).remove(encodedResource);

if(((Set)currentResources).isEmpty()) {

this.resourcesCurrentlyBeingLoaded.remove();

}

}

return var5;

}

}protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {

try {

//@1将XML文件转换为DOM对象,解析过程由documentLoader实现

Document doc = this.doLoadDocument(inputSource, resource);

//@2这里是启动对Bean定义解析的详细过程,该解析过程会用到Spring的Bean配置规则

return this.registerBeanDefinitions(doc, resource);

} catch (BeanDefinitionStoreException var4) {

throw var4;

} catch (SAXParseException var5) {

throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var5.getLineNumber() + " in XML document from " + resource + " is invalid", var5);

} catch (SAXException var6) {

throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var6);

} catch (ParserConfigurationException var7) {

throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var7);

} catch (IOException var8) {

throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var8);

} catch (Throwable var9) {

throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var9);

}

}

@1//使用标准的JAXP将载入的Bean定义资源转换成document对象

public Document loadDocument(InputSource inputSource, EntityResolver entityResolver, ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {

//创建文件解析器工厂

DocumentBuilderFactory factory = this.createDocumentBuilderFactory(validationMode, namespaceAware);

if(logger.isDebugEnabled()) {

logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");

}

//创建文档解析器

DocumentBuilder builder = this.createDocumentBuilder(factory, entityResolver, errorHandler);

//解析Spring的Bean定义资源

return builder.parse(inputSource);

}

protected DocumentBuilderFactory createDocumentBuilderFactory(int validationMode, boolean namespaceAware) throws ParserConfigurationException {

//创建文档解析工厂

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

factory.setNamespaceAware(namespaceAware);

if(validationMode != 0) {

//设置解析XML的校验

factory.setValidating(true);

if(validationMode == 3) {

factory.setNamespaceAware(true);

try {

factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");

} catch (IllegalArgumentException var6) {

ParserConfigurationException pcex = new ParserConfigurationException("Unable to validate using XSD: Your JAXP provider [" + factory + "] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? Upgrade to Apache Xerces (or Java 1.5) for full XSD support.");

pcex.initCause(var6);

throw pcex;

}

}

}

return factory;

}

Spring IoC容器根据定位的Bean定义资源文件,将其加载读入并转换成为Document对象过程完成。

下面是 Spring IoC容器将载入的Bean定义资源文件转换为Document对象之后,是如何将其解析为Spring IoC管理的Bean对象并将其注册到容器中的

@2//按照Spring的Bean语义要求将Bean定义资源解析并转换为容器内部数据结构

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {

/得到BeanDefinitionDocumentReader来对xml格式的BeanDefinition解析

BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();

//获得容器中注册的Bean数量

int countBefore = this.getRegistry().getBeanDefinitionCount();

//解析过程入口,这里使用了委派模式,BeanDefinitionDocumentReader只是个接口

//具体的解析实现过程有实现类DefaultBeanDefinitionDocumentReader完成

//@1

documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));

/统计解析的Bean数量

return this.getRegistry().getBeanDefinitionCount() - countBefore;

}

//创建BeanDefinitionDocumentReader对象,解析Document对象

protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {

return (BeanDefinitionDocumentReader)BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));

}

DefaultBeanDefinitionDocumentReader 解析document对象按照spring Bean的定义规则转换为BeanDefinition

@1public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {

public static final String BEAN_ELEMENT = "bean";

public static final String NESTED_BEANS_ELEMENT = "beans";

public static final String ALIAS_ELEMENT = "alias";

public static final String NAME_ATTRIBUTE = "name";

public static final String ALIAS_ATTRIBUTE = "alias";

public static final String IMPORT_ELEMENT = "import";

public static final String RESOURCE_ATTRIBUTE = "resource";

public static final String PROFILE_ATTRIBUTE = "profile";

protected final Log logger = LogFactory.getLog(this.getClass());

private XmlReaderContext readerContext;

private BeanDefinitionParserDelegate delegate;

public DefaultBeanDefinitionDocumentReader() {

}

//根据Spring DTD对Bean的定义规则解析Bean定义Document对象

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {

//获得XML描述符

this.readerContext = readerContext;

this.logger.debug("Loading bean definitions");

//获得Document的根元素

Element root = doc.getDocumentElement();

this.doRegisterBeanDefinitions(root);

}

protected final XmlReaderContext getReaderContext() {

return this.readerContext;

}

protected Object extractSource(Element ele) {

return this.getReaderContext().extractSource(ele);

}

//具体的解析过程由BeanDefinitionParserDelegate实现,

//BeanDefinitionParserDelegate中定义了Spring Bean定义XML文件的各种元素

protected void doRegisterBeanDefinitions(Element root) {

BeanDefinitionParserDelegate parent = this.delegate;

this.delegate = this.createDelegate(this.getReaderContext(), root, parent);

if(this.delegate.isDefaultNamespace(root)) {

String profileSpec = root.getAttribute("profile");

if(StringUtils.hasText(profileSpec)) {

String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");

if(!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {

if(this.logger.isInfoEnabled()) {

this.logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());

}

return;

}

}

}

//在解析Bean定义之前,进行自定义的解析,增强解析过程的可扩展性

this.preProcessXml(root);

//从Document的根元素开始进行Bean定义的Document对象

this.parseBeanDefinitions(root, this.delegate);

//在解析Bean定义之后,进行自定义的解析,增加解析过程的可扩展性

this.postProcessXml(root);

this.delegate = parent;

}

//创建BeanDefinitionParserDelegate,用于完成真正的解析过程

protected BeanDefinitionParserDelegate createDelegate(XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {

BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);

//BeanDefinitionParserDelegate初始化Document根元素

delegate.initDefaults(root, parentDelegate);

return delegate;

}

//使用Spring的Bean规则从Document的根元素开始进行Bean定义的Document对象

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {

//Bean定义的Document对象使用了Spring默认的XML命名空间

if(delegate.isDefaultNamespace(root)) {

//获取Bean定义的Document对象根元素的所有子节点

NodeList nl = root.getChildNodes();

for(int i = 0; i < nl.getLength(); ++i) {

Node node = nl.item(i);

//获得Document节点是XML元素节点

if(node instanceof Element) {

Element ele = (Element)node;

//Bean定义的Document的元素节点使用的是Spring默认的XML命名空间

if(delegate.isDefaultNamespace(ele)) {

//使用Spring的Bean规则解析元素节点

this.parseDefaultElement(ele, delegate);

} else {

//没有使用Spring默认的XML命名空间,则使用用户自定义的解//析规则解析元素节点

delegate.parseCustomElement(ele);

}

}

}

} else {

//Document的根节点没有使用Spring默认的命名空间,则使用用户自定义的

//解析规则解析Document根节点

delegate.parseCustomElement(root);

}

}

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {

//如果元素节点是导入元素,进行导入解析

if(delegate.nodeNameEquals(ele, "import")) {

this.importBeanDefinitionResource(ele);

} else if(delegate.nodeNameEquals(ele, "alias")) {

//如果元素节点是别名元素,进行别名解析

this.processAliasRegistration(ele);

} else if(delegate.nodeNameEquals(ele, "bean")) {

//元素节点既不是导入元素,也不是别名元素,即普通的元素,

//按照Spring的Bean规则解析元素

this.processBeanDefinition(ele, delegate);

} else if(delegate.nodeNameEquals(ele, "beans")) {

//如果元素节点是元素注册为BeanDefintion

this.doRegisterBeanDefinitions(ele);

}

}

//解析导入元素,从给定的导入路径加载Bean定义资源到Spring IoC容器中

protected void importBeanDefinitionResource(Element ele) {

/获取给定的导入元素的location属性

String location = ele.getAttribute("resource");

if(!StringUtils.hasText(location)) {

this.getReaderContext().error("Resource location must not be empty", ele);

} else {

//获取location的值

location = this.getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);

Set actualResources = new LinkedHashSet(4);

//标识给定的导入元素的location是否是绝对路径

boolean absoluteLocation = false;

try {

absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();

} catch (URISyntaxException var11) {

;

}

int importCount;

if(absoluteLocation) {

try {

//使用资源读入器加载给定路径的Bean定义资源

importCount = this.getReaderContext().getReader().loadBeanDefinitions(location, actualResources);

if(this.logger.isDebugEnabled()) {

this.logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");

}

} catch (BeanDefinitionStoreException var10) {

this.getReaderContext().error("Failed to import bean definitions from URL location [" + location + "]", ele, var10);

}

} else {

//给定的导入元素的location是相对路径

try {

Resource relativeResource = this.getReaderContext().getResource().createRelative(location);

if(relativeResource.exists()) {

//使用资源读入器加载Bean定义资源

importCount = this.getReaderContext().getReader().loadBeanDefinitions(relativeResource);

actualResources.add(relativeResource);

} else {

String baseLocation = this.getReaderContext().getResource().getURL().toString();

importCount = this.getReaderContext().getReader().loadBeanDefinitions(StringUtils.applyRelativePath(baseLocation, location), actualResources);

}

if(this.logger.isDebugEnabled()) {

this.logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");

}

} catch (IOException var8) {

this.getReaderContext().error("Failed to resolve current resource location", ele, var8);

} catch (BeanDefinitionStoreException var9) {

this.getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]", ele, var9);

}

}

//在解析完元素之后,发送容器导入其他资源处理完成事件

Resource[] actResArray = (Resource[])actualResources.toArray(new Resource[actualResources.size()]);

this.getReaderContext().fireImportProcessed(location, actResArray, this.extractSource(ele));

}

}

//解析别名元素,为Bean向Spring IoC容器注册别名

protected void processAliasRegistration(Element ele) {

//获取别名元素中name的属性值

String name = ele.getAttribute("name");

//获取别名元素中alias的属性值

String alias = ele.getAttribute("alias");

boolean valid = true;

if(!StringUtils.hasText(name)) {

this.getReaderContext().error("Name must not be empty", ele);

valid = false;

}

if(!StringUtils.hasText(alias)) {

this.getReaderContext().error("Alias must not be empty", ele);

valid = false;

}

if(valid) {

try {

//向容器的资源读入器注册别名

this.getReaderContext().getRegistry().registerAlias(name, alias);

} catch (Exception var6) {

this.getReaderContext().error("Failed to register alias '" + alias + "' for bean with name '" + name + "'", ele, var6);

}

//在解析完元素之后,发送容器别名处理完成事件

this.getReaderContext().fireAliasRegistered(name, alias, this.extractSource(ele));

}

}

//解析Bean定义资源Document对象的普通元素

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {

// BeanDefinitionHolder是对BeanDefinition的封装,即Bean定义的封装类

//对Document对象中元素的解析由BeanDefinitionParserDelegate实现 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

if(bdHolder != null) {

bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

try {

//向Spring IoC容器注册解析得到的Bean定义,这是Bean定义向IoC容器注册的入口

BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());

} catch (BeanDefinitionStoreException var5) {

this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);

}

//在完成向Spring IoC容器注册解析得到的Bean定义之后,发送注册事件

this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));

}

}

protected void preProcessXml(Element root) {

}

protected void postProcessXml(Element root) {

}

}

通过上述Spring IoC容器对载入的Bean定义Document解析可以看出,我们使用Spring时,在Spring配置文件中可以使用元素来导入IoC容器所需要的其他资源,Spring IoC容器在解析时会首先将指定导入的资源加载进容器中。使用别名时,Spring IoC容器首先将别名元素所定义的别名注册到容器中。

对于既不是元素,又不是元素的元素,即Spring配置文件中普通的元素的解析由BeanDefinitionParserDelegate类的parseBeanDefinitionElement方法来实现。

下面是针对对Bean元素的解析过程//解析Bean定义资源文件中的元素,这个方法中主要处理元素的id,name

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {

//获取id属性

String id = ele.getAttribute("id");

//获取name属性

String nameAttr = ele.getAttribute("name");

List aliases = new ArrayList();

//将Bean元素的name属性全部放到alias属性里面

if(StringUtils.hasLength(nameAttr)) {

String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");

aliases.addAll(Arrays.asList(nameArr));

}

String beanName = id;

if(!StringUtils.hasText(id) && !aliases.isEmpty()) {

beanName = (String)aliases.remove(0);

if(this.logger.isDebugEnabled()) {

this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");

}

}

if(containingBean == null) {

//检查bean元素的id和name是否是唯一的

this.checkNameUniqueness(beanName, aliases, ele);

}

//详细对元素中配置的Bean定义进行解析的地方

AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);

if(beanDefinition != null) {

if(!StringUtils.hasText(beanName)) {

try {

if(containingBean != null) {

//判断如果没有id和name属性时候是否包含子元素的

beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);

} else {

//如果元素中没有配置id、别名或者name,且包含了子//元素,为解析的Bean使用别名向IoC容器注册

beanName = this.readerContext.generateBeanName(beanDefinition);

String beanClassName = beanDefinition.getBeanClassName();

if(beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {

aliases.add(beanClassName);

}

}

if(this.logger.isDebugEnabled()) {

this.logger.debug("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");

}

} catch (Exception var9) {

this.error(var9.getMessage(), ele);

return null;

}

}

String[] aliasesArray = StringUtils.toStringArray(aliases);

return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);

} else {

return null;

}

}

//详细解析bean元素的地方

public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {

this.parseState.push(new BeanEntry(beanName));

String className = null;

//是否包含class属性

if(ele.hasAttribute("class")) {

//获取class属性值 不做实例化,bean的实例化是在第一次获取bean的时候完成,这里只获取class的值

className = ele.getAttribute("class").trim();

}

try {

String parent = null;

//如果元素中配置了parent属性,则获取parent属性的值

if(ele.hasAttribute("parent")) {

parent = ele.getAttribute("parent");

}

//根据元素配置的class名称和parent属性值创建BeanDefinition

//为载入Bean定义信息做准备

AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);

//对当前的元素中配置的一些属性进行解析和设置,如配置的单态(singleton)属性等

this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);

//为元素解析的Bean设置description信息 bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));

//对元素的meta(元信息)属性解析

this.parseMetaElements(ele, bd);

//对元素的lookup-method属性解析

this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());

//对元素的replaced-method属性解析

this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

//解析元素的构造方法设置

this.parseConstructorArgElements(ele, bd);

//解析元素的设置

this.parsePropertyElements(ele, bd);

//解析元素的qualifier属性

this.parseQualifierElements(ele, bd);

bd.setResource(this.readerContext.getResource());

bd.setSource(this.extractSource(ele));

AbstractBeanDefinition var7 = bd;

return var7;

} catch (ClassNotFoundException var13) {

this.error("Bean class [" + className + "] not found", ele, var13);

} catch (NoClassDefFoundError var14) {

this.error("Class that bean class [" + className + "] depends on not found", ele, var14);

} catch (Throwable var15) {

this.error("Unexpected failure during bean definition parsing", ele, var15);

} finally {

this.parseState.pop();

}

return null;

}

通过对上述源码的分析,就会明白我们在Spring配置文件中元素的中配置的属性就是通过该方法解析和设置到Bean中去的。

注意:在解析元素过程中没有创建和实例化Bean对象,只是创建了Bean对象的定义类BeanDefinition,将元素中的配置信息设置到BeanDefinition中作为记录,当依赖注入时才使用这些记录信息创建和实例化具体的Bean对象。

上面方法中一些对一些配置如元信息(meta)、qualifier等的解析,我们在Spring中配置时使用的也不多,我们在使用Spring的元素时,配置最多的是属性。

调用BeanDefinitionReaderUtils的registerBeanDefinition方法向IoC容器注册解析的Beanprotected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {

BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

if(bdHolder != null) {

//通过对document对象的解析和封装返回一个BeanDefinitionHolder

bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

try {

//通过这个holder来注册bean对象

BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());

} catch (BeanDefinitionStoreException var5) {

this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);

}

this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));

}

}

当调用BeanDefinitionReaderUtils向IoC容器注册解析的BeanDefinition时,真正完成注册功能的是DefaultListableBeanFactory。public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {

String beanName = definitionHolder.getBeanName();

registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

String[] aliases = definitionHolder.getAliases();

if(aliases != null) {

String[] var4 = aliases;

int var5 = aliases.length;

for(int var6 = 0; var6 < var5; ++var6) {

String alias = var4[var6];

registry.registerAlias(beanName, alias);

}

}

}

DefaultListableBeanFactory registerBeanDefinition方法//存储注册的俄BeanDefinition

private final Map beanDefinitionMap = new ConcurrentHashMap(256);

//向IoC容器注册解析的BeanDefiniton

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {

Assert.hasText(beanName, "Bean name must not be empty");

Assert.notNull(beanDefinition, "BeanDefinition must not be null");

//校验解析的BeanDefiniton

if(beanDefinition instanceof AbstractBeanDefinition) {

try {

((AbstractBeanDefinition)beanDefinition).validate();

} catch (BeanDefinitionValidationException var9) {

throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);

}

}

BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);

if(oldBeanDefinition != null) {

if(!this.isAllowBeanDefinitionOverriding()) {

throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");

}

if(oldBeanDefinition.getRole() < beanDefinition.getRole()) {

if(this.logger.isWarnEnabled()) {

this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");

}

} else if(!beanDefinition.equals(oldBeanDefinition)) {

if(this.logger.isInfoEnabled()) {

this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");

}

} else if(this.logger.isDebugEnabled()) {

this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");

}

this.beanDefinitionMap.put(beanName, beanDefinition);

} else {

if(this.hasBeanCreationStarted()) {

Map var4 = this.beanDefinitionMap;

//注册的过程中需要线程同步,以保证数据的一致性

synchronized(this.beanDefinitionMap) {

//把bean存放到map中

this.beanDefinitionMap.put(beanName, beanDefinition);

List updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);

updatedDefinitions.addAll(this.beanDefinitionNames);

updatedDefinitions.add(beanName);

this.beanDefinitionNames = updatedDefinitions;

if(this.manualSingletonNames.contains(beanName)) {

Set updatedSingletons = new LinkedHashSet(this.manualSingletonNames);

updatedSingletons.remove(beanName);

this.manualSingletonNames = updatedSingletons;

}

}

} else {

this.beanDefinitionMap.put(beanName, beanDefinition);

this.beanDefinitionNames.add(beanName);

this.manualSingletonNames.remove(beanName);

}

this.frozenBeanDefinitionNames = null;

}

if(oldBeanDefinition != null || this.containsSingleton(beanName)) {

this.resetBeanDefinition(beanName);

}

}

至此,Bean定义资源文件中配置的Bean被解析过后,已经注册到IoC容器中,被容器管理起来,真正完成了IoC容器初始化所做的全部工作。现 在IoC容器中已经建立了整个Bean的配置信息,这些BeanDefinition信息已经可以使用,并且可以被检索,IoC容器的作用就是对这些注册的Bean定义信息进行处理和维护。这些的注册的Bean定义信息是IoC容器控制反转的基础,正是有了这些注册的数据,容器才可以进行依赖注入。查看原文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值