Spring IOC-资源加载策略


用一个案例来引入:


		ResourceLoader resourceLoader = new DefaultResourceLoader();
		
		ClassPathResource resource = (ClassPathResource)resourceLoader.getResource("bean.xml");
		DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); 
		XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); 
		reader.loadBeanDefinitions(resource); 

		TestService1 testService1 = (TestService1)factory.getBean("TestService1");
		testService1.print();

和我们常用的ApplicationContext不同,这个代码将ioc的构造细分开了,这样更加容易理解每个部分的工作流程。今天先学习Resource接口和ResourceLoader。也就是这个代码对应的前两句。

统一资源接口

在Spring使用的时候需要读入资源,比如bean.xml也是需要读入的资源。有加载资源的需求就有加载资源的策略。在Spring当中资源加载应当满足以下需求:

  1. 职能划分清楚。资源的定义和资源的加载应该要有一个清晰的界限
  2. 统一的抽象。统一的资源定义和资源加载策略。资源加载后要返回统一的抽象给客户端,客户端要对资源进行怎样的处理,应该由抽象资源接口来界定。

Spring中的统一资源接口是Resource接口。在Spring中所有的资源都是通过Resource接口来抽象的。 它继承 org.springframework.core.io.InputStreamSource接口。作为所有资源的统一抽象,Resource 定义了一些通用的方法,由子类 AbstractResource 提供统一的默认实现。定义如下:

public interface Resource extends InputStreamSource {
   

	/**
	 *判断资源是否存在
	 */
	boolean exists();

	/**
	 * 判断资源是否可读
	 */
	default boolean isReadable() {
   
		return true;
	}

	/**
	 * 资源所代表的句柄是否被一个stream打开了
	 */
	default boolean isOpen() {
   
		return false;
	}

	/**
	 * 是否为一个File
	 */
	default boolean isFile() {
   
		return false;
	}

	/**
	 * 返回资源的url句柄
	 */
	URL getURL() throws IOException;

	/**
	 * 返回资源的URI句柄
	 */
	URI getURI() throws IOException;

	/**
	 * 返回File的句柄
	 */
	File getFile() throws IOException;

	/**
	 * 返回一个ReadableByteChannel,这个用于nio类型的资源
	 */
	default ReadableByteChannel readableChannel() throws IOException {
   
		return Channels.newChannel(getInputStream());
	}

	/**
	 * 资源内容的长度
	 */
	long contentLength() throws IOException;

	/**
	 * 资源最后的修改时间
	 */
	long lastModified() throws IOException;

	/**
	 * 根据资源的相对路径创建新资源
	 */
	Resource createRelative(String relativePath) throws IOException;

	/**
	 * 资源的文件名
	 */
	@Nullable
	String getFilename();

	/**
	 * 资源的描述
	 */
	String getDescription();

}

Resource 接口可以说是资源的顶级接口,它的默认实现类是AbstractResource类。这个体系中不同的资源提供了不同的具体实现,Resource的类图为:
在这里插入图片描述

  • AbstractResource :Resource接口的默认实现类,里面包含了很多方法的默认实现,我们自定义Resource的时候可以直接继承这个类。
  • FileSystemResource : 对 java.io.File 类型资源的封装 ,支持NIO类型。
  • ByteArrayResource : 对字节数组提供的数据的封装。
  • UrlResource :对 java.net.URL类型资源的封装。内部委派 URL 进行具体的资源操作。
  • ClassPathResource :class path 类型资源的实现。使用给定的 ClassLoader 或者给定的 Class 来加载资源。实例中使用的就是这个。
  • InputStreamResource :将给定的 InputStream 作为一种资源的 Resource 的实现类。

AbstractResource

Resource的默认抽象实现:

public abstract class AbstractResource implements Resource {
   

	/**
	 * 判断文件是否存在,若判断过程中出现异常,会关闭对应的流。
	 */
	@Override
	public boolean exists() {
   
		// getFile()是需要子类自己实现的
		try {
   
			return getFile().exists();
		}
		catch (IOException ex) {
   
			// Fall back to stream existence: can we open the stream?
			try {
   
				getInputStream().close();
				return true;
			}
			catch (Throwable isEx) {
   
				return false;
			}
		}
	}

	/**
	 * This implementation always returns {@code true}.
	 */
	@Override
	public boolean isReadable() {
   
		return true;
	}

	/**
	 * This implementation always returns {@code false}.
	 */
	@Override
	public boolean isOpen() {
   
		return false;
	}

	/**
	 * This implementation always returns {@code false}.
	 */
	@Override
	public boolean isFile() {
   
		return false;
	}

	/**
	 * This implementation throws a FileNotFoundException, assuming
	 * that the resource cannot be resolved to a URL.
	 */
	@Override
	public URL getURL() throws IOException {
   
		throw new FileNotFoundException(getDescription() + " cannot be resolved to URL");
	}

	/**
	 * This implementation builds a URI based on the URL returned
	 * by {@link #getURL()}.
	 */
	@Override
	public URI getURI() throws IOException {
   
		URL url = getURL();
		try {
   
			return ResourceUtils.toURI(url);
		}
		catch (URISyntaxException ex) {
   
			throw new NestedIOException("Invalid URI [" + url + "]", ex);
		}
	}

	/**
	 * This implementation throws a FileNotFoundException, assuming
	 * that the resource cannot be resolved to an absolute file path.
	 */
	@Override
	public File getFile() throws IOException {
   
		throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");
	}

	/**
	 * 根据 getInputStream() 的返回结果构建 ReadableByteChannel.
	 */
	@Override
	public ReadableByteChannel readableChannel() throws IOException {
   
		return Channels.newChannel(getInputStream());
	}

	/**
	 * 获取资源长度,通过全部读一遍来获取资源的字节长度。
	 */
	@Override
	public long contentLength() throws IOException {
   
		InputStream is = getInputStream();
		try {
   
			long size =
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值