配置文件的封装

BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanTest.xml"));

首先调用ClasspathResource的构造函数来构造Resource资源文件的实例对象,这样后续的资源处理就可以用Resource提供的各种服务来操作了,当有了Resource后就可以进行XmlBeanFactory的初始化了。

在java中,将不同来源的资源抽象成URL,通过注册不同的handler来处理不同来源的资源读取逻辑,一般handler的类型使用不同前缀来识别,如"file:"、"http:"、"jar:"等,然而URL没有默认定义相对于Classpath或servletContext等资源的handler。

spring对其内部使用到的资源实现了自己的抽象结构:Resource接口来封装底层资源。

public interface InputStreamSource {
	InputStream getInputStream() throws IOException;
}
public interface Resource extends InputStreamSource {
	boolean exists();
	boolean isReadable();
	boolean isOpen();
	URL getURL() throws IOException;
	URI getURI() throws IOException;
	File getFile() throws IOException;
	long contentLength() throws IOException;
	long lastModified() throws IOException;
	Resource createRelative(String relativePath) throws IOException;
	String getFilename();
	String getDescription();
}

InputStreamSource封装任何能返回InputStream的类,如File、Classpath下的资源和Byte Array等。

Resource接口抽象了所有Spring内部使用到的底层资源:File、URL、Classpath等。它定义了3个判断当前资源状态的方法:存在性(exist)、可读性(isReadable)、是否处于打开状态(isOpen),还提供了不同资源到URL、URI、File类型的转换,以及获取lastModified属性、文件名的方法。为了便于操作,Resource还提供了基于当前资源创建一个相对资源的方法:createRelative()。getDescription()方法用于在错误处理中打印信息。

对不同来源的资源文件都有相应的Resource实现:文件(FileSystemResource)、Classpath(ClasspathResource)、URL资源(UrlResource)、InputStream(InputStreamResource)、Byte数组(ByteArrayResource)等。

Resource接口的层级结构:


getInputStream()的实现:

ClasspathResource:使用calss或者classLoader提供的底层方法进行调用

public InputStream getInputStream() throws IOException {
		InputStream is;
		if (this.clazz != null) {
			is = this.clazz.getResourceAsStream(this.path);
		}
		else {
			is = this.classLoader.getResourceAsStream(this.path);
		}
		if (is == null) {
			throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
		}
		return is;
	}

FileSystemResource:直接使用FileInputStream对文件进行实例化

	public InputStream getInputStream() throws IOException {
		return new FileInputStream(this.file);
	}

当Resource相关类完成了对配置文件进行 封装后配置文件的读取工作就全权交给XmlBeanDefinitionReader来处理了。

BeanFactory bf = new XmlBeanFactory(Resource resourec);

XmlBeanFactory.java

public XmlBeanFactory(Resource resource) throws BeansException {
	//调用第二个构造方法
	this(resource, null);
}
//parentBeanFactory为父类BeanFactory用于factory合并,可以为空
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
	super(parentBeanFactory);
	this.reader.loadBeanDefinitions(resource);
 }

this.reader.loadBeanDefinitions(resource)才是资源加载的真正实现。

super(parentBeanFactory),跟踪代码到父类AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory

public AbstractAutowireCapableBeanFactory() {
    super();
    ignoreDependencyInterface(BeanNameAware.class);
    ignoreDependencyInterface(BeanFactoryAware.class);
    ignoreDependencyInterface(BeanClassLoaderAware.class);
}


ignoreDependencyInterface方法的主要功能是忽略给定接口的自动装配功能。举例来说,当A中有属性B,那么当spring在获取A的bean的时候如果其属性B还没有初始化,那么spring自动初始化B,这也是spring中提供的一个重要特性。但是,某些情况下,B不会被初始化,其中的一种情况是B实现了BeanNameAware接口。spring是这样介绍的:自动装配是忽略给定的依赖接口,典型的应用是通过其他方式解析Application上下文注册依赖,类似于BeanFactory通过BeanFactoryAware进行注入或者ApplicationContext通过ApplicationContextAware进行注入。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值