Spring bean的初始化源码分析-XML解析
XML解析部分,XML解析最终会将XML中配置的bean或者标签需要扫描的bean,都准备好,生成beanDefinition,用于后续的bean实例化
XmlBeanFactory bf = new XmlBeanFactory(new ClassPathResource("/spring-code-test.xml"));
DefaultListableBeanFactory 类是 spring bean 加载的核心类, XMLBeanFactory继承,实际是在里面封装了另一个类XmlBeanDefinitionReader, 这个类用于解析xml。本节主要讲这个类如何解析XML的。
public class XmlBeanFactory extends DefaultListableBeanFactory { private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); public XmlBeanFactory(Resource resource) throws BeansException { this(resource, null); } public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) { super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); } }
实际XML的加载过程封装在 XmlBeanDefinitionReader.loadBeanDefinitions 方法里了,实际过程是
1. 先对 输入的 文件进行 Resource 封装, new ClassPathResource("/spring-code-test.xml"), Resource对象传入XmlBeanDefinitionReader
2. XmlBeanDefinitionReader
2.1 对输入对象进行encoding封装
2.2 获取XML的验证模式,同时确认解析标签使用的XSD文档和对应标签解析的jar路径)
2.3 加载XML文件,得到对应的Document对象
// XmlBeanDefinitionReader public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { ...... try { InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } ...... } protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) { try { // XML 生成 document对象,doLoadDocument 内部会确认 XSD文档和解析标签所使用的jar包 Document doc = doLoadDocument(inputSource, resource); return registerBeanDefinitions(doc, resource); } } public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { // 实际负责加载的document的类是 DefaultBeanDefinitionDocumentReader BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; }
DefaultBeanDefinitionDocumentReader 类做的事情就是根据 document ,进行element解析
// DefaultBeanDefinitionDocumentReader 类 public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); // 获取root节点,进行解析 Element root = doc.getDocumentElement(); doRegisterBeanDefinitions(root); } /** * Parse the elements at the root level in the document: * "import", "alias", "bean". * @param root the DOM root element of the document */ // 解析具体实现方法 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(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; if (delegate.isDefaultNamespace(ele)) { // 解析默认标签 parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } } // 解析默认标签,bean标签相关 protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance. BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
相关推荐
一旦XML配置加载到Spring容器中,容器将根据配置创建Bean实例,并按照定义进行初始化、依赖注入,最后完成Bean的生命周期管理。 10. **实践操作**: 在实际开发中,我们可以使用Eclipse的Spring插件来简化Bean...
下面将详细介绍如何通过不同方式定义Spring Bean的初始化和销毁回调方法。 **初始化回调方法** 1. **@PostConstruct注解** 这个Java标准注解用于标记一个方法,该方法将在对象完全构造后但在业务逻辑执行前被调用...
在Spring框架中,Bean配置是核心概念之一,它关乎到对象的创建、初始化、装配以及管理。本节我们将深入探讨Spring中的Bean配置,主要聚焦在XML配置方式,因为这是Spring早期版本中最常用的方式,尽管在现代Spring...
在Spring框架中,Bean配置是核心概念之一,它关乎到对象的创建、初始化、依赖注入以及生命周期管理。在"Spring--2.Spring 中的 Bean 配置-2-2"这个主题下,我们将深入探讨如何在Spring中进行Bean的详细配置。 1. **...
- **Bean管理**:Spring容器负责创建、初始化、配置和管理Bean,以及它们之间的依赖关系。 - **MVC**:Spring MVC是Spring框架的一部分,用于构建Web应用程序,提供了模型、视图和控制器的分离。 2. **MyBatis**...
- **XML配置**:在传统的Spring应用中,Bean的定义通常写在XML配置文件中,如`springbean-xml`中的配置。 - **注解配置**:使用`@Component`,`@Service`,`@Repository`和`@Controller`注解标记类,配合`@...
"粗略实现spring创建bean"这个主题主要涉及到Spring如何初始化、配置以及管理Java对象,也就是我们所说的Bean。下面我们将深入探讨Spring Bean的生命周期、配置方式以及相关API。 1. Spring Bean 的生命周期 - ...
在Spring框架中,Bean配置是核心概念之一,它关乎到对象的创建、初始化、装配以及管理。本节我们将深入探讨Spring中的Bean配置,主要关注如何通过XML、注解以及Java配置方式来管理Bean。 首先,让我们从XML配置说起...
BeanFactory是Spring中最基本的IOC容器接口,它负责管理Bean的生命周期,包括实例化、初始化、销毁等操作。在实际应用中,我们通常使用其子类ApplicationContext,它提供了更丰富的功能,如国际化支持、事件发布等。...
3. **@PostConstruct与初始化回调**:Spring允许我们在Bean初始化后执行特定代码,通常通过`@PostConstruct`注解的方法来实现。如果这个方法被意外地调用了两次,那么Bean也会被构造两次。检查是否有多处调用或配置...
通过实现`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`方法,可以在Bean初始化前后进行额外的操作。 在Spring容器中,Bean的生命周期管理也支持通过`BeanDefinition`进行定制。例如,...
1. **装载Bean定义**:Spring容器读取XML配置文件,解析Bean的定义,包括其类型、依赖关系、初始化方法等。 2. **创建Bean实例**:根据`lazy-init`属性决定是否立即创建实例。对于`singleton`作用域的Bean,无论`...
本文将深入探讨Spring中的Bean配置,主要基于标题"Spring--2.Spring 中的 Bean 配置-1"及其相关的上下文。 首先,我们要理解什么是Bean。在Spring中,Bean指的是由Spring容器管理的对象,这些对象可以通过XML、注解...
但是,这并不总是可靠的,因为Spring通常会延迟初始化Bean,除非显式要求或存在依赖关系。 2. **依赖注入**:Spring容器会根据Bean之间的依赖关系来决定实例化顺序。如果一个Bean依赖于另一个Bean,那么被依赖的...
- **init-method属性**:指定Bean初始化方法,通常用于资源的初始化。 - **destroy-method属性**:指定Bean销毁方法,用于清理资源。 - **factory-bean/factory-method属性**:通过工厂方法创建Bean。`factory-...
7. **Bean初始化**: 实例化完成后,Spring会执行Bean的初始化方法,包括调用`@PostConstruct`注解的方法。同时,如果Bean实现了InitializingBean接口,其`afterPropertiesSet()`方法也会被调用。 8. **初始化后...
Spring Bean 是 Spring 框架的核心概念,它代表了应用程序中的一个对象,这个对象可以被 Spring 容器管理,包括创建、初始化、装配、销毁等生命周期过程。在 Spring 中,Bean 定义是由 `BeanDefinition` 接口来表示...
1. **复杂初始化逻辑**:如果一个Bean的创建需要特殊的初始化步骤,如执行特定的代码、加载配置或资源,可以将这些逻辑封装到FactoryBean中。 2. **代理对象**:FactoryBean可用于创建代理对象,比如AOP代理,这...
通过这个解析过程,Spring能够根据XML配置文件动态地创建和管理bean,实现DI。当需要某个bean时,Spring会自动查找并创建该bean及其依赖的bean,从而简化了代码,提高了可维护性。总的来说,理解Spring的XML解析原理...