【Spring】著作阅读笔记——ApplicationContext的统一资源管理

23 篇文章 2 订阅
16 篇文章 0 订阅

前言

Spring的出现,把Java net包下的URL的资源类型做了扩展。明确了资源的定位及表示的边界。解耦了资源的定位和表示,以下将整理Spring为统一资源管理做出的努力。(文末给出获取bean的工具类,得益于Spring对资源的重新设计。)

Java 对URL的狭义解释

广义的URL解释 ,大意为:
因特网上访问某一资源的唯一标志:形如<方案>:<方案描述部分>,以下都为URL的表示

  • http://www.baidu.com
  • file://SD/packet.xml
  • thunder://QUFodHRwOi8vM
    如果将以上的URL告诉浏览器,浏览器会使用对应的方案(软件),委托方案(软件)执行方案描述部分。如使用file方案定位到/SD//packet.xml ,即打开本地的资源管理器到目录//SD/packet.xml下。
    Java8.net 下的URL是提供了getFile()方法,但是形同虚设
    在这里插入图片描述

Spring 重新设计了对资源的抽象

##

  • org.springframework.core.io.Resource 作为资源的抽象和访问接口。URL使用file方案的标准
    在这里插入图片描述
  • 还有其他URL支持的资源不一一展示,但是Spring 对资源的解读明显是比原生Java更具体的

Spring 获取更广义的URL —— ResourceLoader

形如<方案>:<方案描述部分>

  • DefaultResourceLoader 从classpath中获取,明确了<方案>中是file与http的返回URLResource,未明确返回ClasspathResource

  • FileSystemResourceLoader 明确了<方案>中是file与http的返回URLResource,未明确返回FileSystemResource

  • PathMatchingResourcePatternResolver,默认使用DefaultResourceLoader,并支持批量的资源访问,也可以通过构造方法传入FileSystemResourceLoader。是资源访问的组合拳(功能完备)

为什么要交代ResourceLoader ?

  • 书上没有说,从结果上来看是更好得支持了本地文件的访问,同时解耦了资源的表现,在未来支持Docker资源的访问变成了可能。
  • Spring 使用 PathMatchingResourcePatternResolver 支持统一资源的加载,一般用到classpath下的文件即可,传统的URL习惯告诉程序单个文件的位置,Spring则在URL规范下引入了一种新的协议前缀classpath,Eg:classpath:conf/container-conf.xml, 这种规范为外部化配置打下了基础,也更好得区分本地磁盘中的其他资源

ApplicationContext 作为资源管理者的角色

  • 通常,所有的ApplicationContext实现类会直接会间接地继承AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {

	/** ResourcePatternResolver used by this context. */
	private ResourcePatternResolver resourcePatternResolver;

	public AbstractApplicationContext() {
		this.resourcePatternResolver = getResourcePatternResolver();
	}

	protected ResourcePatternResolver getResourcePatternResolver() {
		return new PathMatchingResourcePatternResolver(this);
	}
}	

以上源码告诉我们的事实:

  1. ApplicationContex实现类 自己可以作为 DefaultResourceLoader
    —— 可访问classpath资源或URL资源

  2. ApplicationContex实现类 持有带有 thisPathMatchingResourcePatternResolver
    值得一提的是这个this是设计模式中:模板方法的一种使用场景,此时的this代表实现类,默认的实现类一定是DefaultResourceLoader (由AbstractApplicationContext extends DefaultResourceLoader决定)。

  3. 对于获取本地的文件,有实现类FileSystemXmlApplicationContext ,其中改写了方法

	@Override
	protected Resource getResourceByPath(String path) {
		if (path.startsWith("/")) {
			path = path.substring(1);
		}
		return new FileSystemResource(path);
	}

	// 原来的方法
	protected Resource getResourceByPath(String path) {
		return new ClassPathContextResource(path, getClassLoader());
	}

解耦了资源表示,拓展就变得方便多了

ApplicationContext 与接口注入

  • 随意找了一个网上的Spring 上下文工具类 (用于在运行时获取Bean),来看看它怎么利用ApplicationContext
@Component
public class SpringUtil implements ApplicationContextAware {
 
    private static ApplicationContext applicationContext;
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }
 
    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
 
    //通过name获取 Bean.
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }
 
    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }
 
    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }
}
  • 接口注入的规范
    Spring 提供了三种依赖注入的实现,其中入侵性比较强的是接口注入,唯一的好处是不需要写xml文件,这里的工具类就是使用这种注入方式。(这个是依赖容器启动时自动扫描接口的特性属于IOC的内容
public interface ApplicationContextAware extends Aware {

	/**
	 * 容器启动后,会把applicationContext实现类注入到工具类里
	 */
	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值