上面一篇提到了bean加载的入口:
AbstractRefreshableApplicationContext的refreshBeanFacotry中有一行代码:
loadBeanDefinitions(beanFactory);
当前的applicationcontext的实现类是xmlwebapplicationContext,所以最终的loadbeanDefinitions(beanFactory)
方法的实现是在xmlwebapplicationContext中:
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = XBeanHelper.createBeanDefinitionReader(this, beanFactory, xmlPreprocessors);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
很容易就能发现,bean的加载的是通过最后一行实现的。继续追踪进入源码:
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
reader.loadBeanDefinitions(configLocation);
}
}
}
现在知道为什么可以在web.xml中配置spring的时候指定多个配置文件了吧?哈哈。
继续追踪XmlBeanDefinitionReader这个类。这个类继承了AbstractBeanDefinitionReader。AbstractBeanDefinitionReader还有一个实现类:PropertiesBeanDefinitionReader。
从名字很容易可以看出spring能支持基于xml和基于properties文件的bean加载方式。XmlBeanDefinitionReader
过把xml加载到一个Document对象里面,然后通过BeanDefinitionDocumentReader来分析这个document对象。
BeanDefinitionDocumentReader的默认实现类是:DefaultBeanDefinitionDocumentReader。
其中注册bean的代码如下:
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);
preProcessXml(root);
parseBeanDefinitions(root, delegate);
postProcessXml(root);
}
spring在这里提供了xml配置文件解析的两个扩展接口:preProcessXml,postProcessXml. 用户可以根据自身需求
扩展这两个接口。下面就关注一下上面代码里面加载bean的核心方法:parseBeanDefinition.
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(delegate.getNamespaceURI(root))) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
String namespaceUri = delegate.getNamespaceURI(ele);
if (delegate.isDefaultNamespace(namespaceUri)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
从上面代码可以看出,xml配置文件里面的<beans></beans>标签里面的闭合标签被解析成一个个Node.然后
调用每个标签的NameSpaceHandler进行标签的解析,并注册相应的bean。比如:解析<aop:config></aop:config>
这种标签时会调用AopNamespaceHandler来进行解析。对于使用默认NameSpace的标签,又分为import,alias,bean三个标签进行解析并注册相应的bean。
至此,bean的注入的轮廓基本清晰了。有兴趣的朋友可以沿着这个思路继续深入一些细节,比如aop的注入等等。
分享到:
相关推荐
### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...
通过XML配置文件或注解,我们可以声明bean之间的依赖关系,使代码更加灵活且易于测试。 2. **Bean容器**:Spring的IoC(Inversion of Control)容器是管理bean的工厂,负责创建、装配和管理bean。在`io.xml`配置...
在Spring源码解析中,时序图用于描绘不同组件之间的调用关系,如AOP代理的生成过程、事件发布机制、数据访问层(DAO)与业务逻辑层(Service)的交互等。这有助于开发者理解Spring如何处理复杂的应用场景。 再者,...
《Spring IOC源码解析(一)——整体介绍》 在深入理解Spring框架的过程中,源码分析是不可或缺的一环。本文将对Spring的IOC(Inversion of Control,控制反转)...希望本文能为你开启Spring源码探索之旅的第一步。
### Spring源码分析之IOC容器深入探讨 #### 一、Spring框架及IOC容器概述 Spring框架作为企业级Java开发中最常用的轻量级框架之一,以其强大的功能和灵活的设计深受开发者们的喜爱。Spring的核心特性之一便是...
在本资源中,我们提供了可以直接导入Eclipse的Spring源码的第五部分,版本为4.3.18。这一版本的Spring包含了众多改进和修复,对于理解Spring的工作原理以及进行自定义开发非常有帮助。 首先,让我们深入了解一下...
### Spring源码解析:IOC容器 #### 一、Spring框架简介 Spring框架是一个开源的轻量级企业级应用开发框架,旨在简化企业级应用的开发过程。它通过一系列的组件和设计模式支持如依赖注入(Dependency Injection, DI...
3. 创建一个`XmlBeanDefinitionReader`,它负责读取和解析XML配置文件,将配置信息加载到bean工厂中。 例如: ```java ClassPathResource res = new ClassPathResource("beans.xml"); DefaultListableBeanFactory ...
本文将深入探讨"spring-demo:spring原始解析"这一主题,带领读者一窥Spring框架的内部工作机制,通过源码分析,帮助开发者更深入地理解Spring的核心概念。 Spring框架的核心在于依赖注入(Dependency Injection,DI...
这一部分涵盖了Spring中简单的属性注入,包括如何在XML配置文件中声明bean的属性,并通过setter方法进行注入。同时也会介绍如何在Java配置中使用@Configuration和@Bean注解来完成相同的功能。 通过这些实例,初学...
在配置文件中,我们能看到bean的定义方式,如class属性指定bean的全限定类名,以及属性注入、构造器注入等配置。在源码中,我们可以研究IoC容器如何解析这些配置,以及如何实例化和初始化bean。 Spring MVC作为Web...
《Spring源码解析》 Spring框架作为Java领域中最为广泛应用的轻量级框架之一,它的设计思想和实现机制对于每一个Java开发者来说都是重要的学习内容。本文将深入探讨Spring的核心组件——IoC(Inversion of Control...
这些类负责加载Bean定义,解析XML配置文件,以及实例化和管理Bean。 通过手动实现和分析Spring的DI,我们可以更深入地理解这个强大的功能,从而在日常开发中更好地利用Spring框架。手写DI源码不仅有助于提高对...
这些配置类基于存在的Bean和属性文件,自动创建和配置所需的Bean。例如,如果classpath中有HSQLDB的JDBC驱动,Spring Boot会自动配置一个内存数据库。 接着,我们转向微服务的关键组件——Spring Cloud。Spring ...
通过运行这些Demo,你可以更直观地了解SpringBoot如何根据类路径和配置文件来决定加载哪些Bean,以及注解如何影响Spring容器的行为。深入学习和理解这些知识点,将有助于你更好地驾驭SpringBoot,提升开发效率,并在...
1. **配置文件解析**:Spring的启动通常始于一个或多个配置文件,如XML或Java配置类。这些配置文件定义了bean的定义,包括bean的类型、属性、依赖关系等。Spring通过BeanDefinitionReader读取这些配置,将其转化为...
5. **关联Job和Trigger**:在Spring配置文件中,使用`org.springframework.scheduling.quartz.JobDetailFactoryBean`定义Job,并使用`org.springframework.scheduling.quartz.CronTriggerFactoryBean`定义Trigger。...
1. **Spring对注解_Annotation_处理源码分析**: - 这部分内容将讲解Spring如何扫描和读取Bean定义,以及如何解析和注入注解配置的资源。它涵盖了Spring的组件扫描机制,如何识别和处理类上的注解,以及注解驱动的...