1 将资源文件封装成Resource
如Resource re = new ClassPathResource("");
2. 将加载好的资源文件 通过XmlBeanFactory初始化
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) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
}
3.加载bean
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
首先使用EncodedResource对resource进行封装,当设置了编码属性,spring会使用相应的编码作为输入流的编码
private EncodedResource(Resource resource, String encoding, Charset charset) {
super();
Assert.notNull(resource, "Resource must not be null");
this.resource = resource;
this.encoding = encoding;
this.charset = charset;
}
public Reader getReader() throws IOException {
if (this.charset != null) {
return new InputStreamReader(this.resource.getInputStream(), this.charset);
}
else if (this.encoding != null) {
return new InputStreamReader(this.resource.getInputStream(), this.encoding);
}
else {
return new InputStreamReader(this.resource.getInputStream());
}
}
上述代码构建好了一个有编码的InputStreamReader
下面这个方法才是真正的数据准备阶段
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<EncodedResource>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
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());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
//通过属性记录已经加载的资源,放入Threadlocal变量中
private final ThreadLocal<Set<EncodedResource>> resourcesCurrentlyBeingLoaded =new NamedThreadLocal<Set<EncodedResource>>("XML bean definition resources currently being loaded");
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
//获取验证模式(DTD XSD两种验证模式)
protected int getValidationModeForResource(Resource resource) {
int validationModeToUse = getValidationMode();
//如果手动指定了验证模式则使用指定的验证模式
if (validationModeToUse != VALIDATION_AUTO) {
return validationModeToUse;
}
//没有指定 则使用自动检测
int detectedMode = detectValidationMode(resource);
if (detectedMode != VALIDATION_AUTO) {
return detectedMode;
}
// Hmm, we didn't get a clear indication... Let's assume XSD,
// since apparently no DTD declaration has been found up until
// detection stopped (before finding the document's root tag).
return VALIDATION_XSD;
}
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
此段代码 主要做了三件事:
获取对xml文件的验证模式
加载xml文件,并得到对应的Document
根据返回的Document注册Bean的信息
分享到:
相关推荐
1. **Spring 事务处理**:Spring 提供了声明式事务管理,允许开发者在配置文件中定义事务边界,无需在业务逻辑代码中显式控制事务开始、提交和回滚。它主要基于AOP代理来实现,通过TransactionInterceptor拦截器进行...
通过这个"spring framework xml配置使用示例",你可以学习到如何使用XML配置文件来设置Spring环境,管理Bean,以及处理Bean之间的依赖关系。在实际开发中,虽然现在的趋势是使用Java配置和注解,但理解XML配置仍然是...
源码分析是理解Spring配置文件的另一个重要途径。Spring框架是开源的,我们可以通过阅读源码来了解其内部工作原理。例如,`ApplicationContext`接口和其实现类如`ClassPathXmlApplicationContext`,它们负责加载和...
Spring提供多种实例化Bean的方式,这里以`XmlBeanFactory`为例,通过`FileSystemResource`加载XML配置文件,然后通过`getBean`方法获取Bean实例。在`getBean`内部,会根据Bean定义创建并初始化Bean对象,包括执行...
以上只是Spring源码分析的部分内容,实际源码中还包括Spring的其他模块,如Spring Batch(批处理)、Spring Security(安全)、Spring Integration(集成)等。理解并掌握Spring源码,有助于我们更好地利用Spring...
### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...
1. 依赖注入:在Spring 1.0中,DI是通过XML配置文件实现的,它允许开发者声明组件间的依赖关系,而不是在代码中硬编码。这样,对象的创建和管理由Spring容器负责,提高了代码的可测试性和可维护性。 2. 控制反转:...
### Spring Security 源码分析知识点 #### 一、Spring Security 概述 Spring Security 是一个强大且可高度定制的身份验证和访问控制框架。它提供了许多功能,包括登录表单、记住密码、CSRF 保护等。为了更好地理解...
最后,我们可以通过`src`目录下的源代码来进一步了解具体的实现细节,例如切面类、被通知的方法以及相关的XML配置文件。通过对这些内容的分析和实践,你可以深入理解Spring 2.0中AOP的概念及其XML配置方式,从而在...
首先,Spring 3.0的一大亮点是增强了对Java 5和6的支持,引入了基于注解的配置,大大减少了XML配置文件的数量和复杂性。开发者可以使用如`@Autowired`、`@Service`、`@Repository`和`@Controller`等注解,直接在类或...
通过对这些模块的源码分析,我们可以深入了解Spring如何实现其强大的功能,并能更好地运用到实际项目中,提升代码质量和可维护性。无论是新手还是经验丰富的开发者,理解Spring的源码都将是一次宝贵的进阶之旅。
1. 创建一个用于加载XML配置文件的抽象资源对象ClassPathResource,这里的配置文件名为beans.xml。 2. 创建一个BeanFactory实现类DefaultListableBeanFactory的实例。 3. 创建一个XmlBeanDefinitionReader实例,并将...
Spring加载XSD文件发生错误的解决方法 在使用 Spring 框架时,可能会遇到加载 XSD 文件发生错误的问题,本文将对此问题进行详细的分析和解决。 问题描述 在使用 Spring 框架时,可能会出现 org.xml.sax....
1. **配置文件解析**:Spring的启动通常始于一个或多个配置文件,如XML或Java配置类。这些配置文件定义了bean的定义,包括bean的类型、属性、依赖关系等。Spring通过BeanDefinitionReader读取这些配置,将其转化为...
《Spring源码分析——ApplicationContext》 在Java世界中,Spring框架是不可或缺的一部分,它以其强大的IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)特性,极大地...
Spring的XML配置文件是其核心特性之一,它允许开发者用XML来声明和配置bean及其依赖关系。在Spring中,`BeanUtils`类提供了基本的对象-XML转换功能,而`XmlBeanDefinitionReader`则负责读取XML配置文件并创建bean...
SpEL允许在配置文件或代码中动态地访问和修改对象属性,这对于依赖注入和条件逻辑的实现至关重要。 `spring-webmvc-4.2.4.RELEASE-sources`是Spring MVC的实现,它是Spring框架用于构建Web应用的核心模块。通过源码...
- 容器通过XML配置文件、Java配置类或基于注解的方式获取Bean的定义信息。 5. **Spring MVC** - Spring MVC是Spring框架的一部分,用于构建Web应用程序,提供模型-视图-控制器(MVC)架构。 - DispatcherServlet...