博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring IoC容器ApplicationContext
阅读量:6947 次
发布时间:2019-06-27

本文共 7791 字,大约阅读时间需要 25 分钟。

ApplicationContext主要实现类

其作用分别是:

  • 在默认情况下,从文件系统加载bean定义以及相关资源的 ApplicationContext 实现。
  • 在默认情况下,从Classpath加载bean定义以及相关资源的 ApplicationContext 实现。
  • Spring提供的用于Web应用程序的 ApplicationContext 实现。

统一资源加载策略

Spring中的Resource

Resource及其主要实现类:

接口定义源码如下:

public interface InputStreamSource {	InputStream getInputStream() throws IOException;}复制代码
public interface Resource extends InputStreamSource {	/**	 * Determine whether this resource actually exists in physical form.	 */	boolean exists();	/**	 * Indicate whether non-empty contents of this resource can be read via	 */	default boolean isReadable() {		return exists();	}	/**	 * Indicate whether this resource represents a handle with an open stream.	 */	default boolean isOpen() {		return false;	}	/**	 * Determine whether this resource represents a file in a file system.	 */	default boolean isFile() {		return false;	}	/**	 * Return a URL handle for this resource.	 */	URL getURL() throws IOException;	/**	 * Return a URI handle for this resource.	 */	URI getURI() throws IOException;	/**	 * Return a File handle for this resource.	 */	File getFile() throws IOException;	/**	 * Return a {
@link ReadableByteChannel}. */ default ReadableByteChannel readableChannel() throws IOException { return Channels.newChannel(getInputStream()); } /** * Determine the content length for this resource. */ long contentLength() throws IOException; /** * Determine the last-modified timestamp for this resource. */ long lastModified() throws IOException; /** * Create a resource relative to this resource. */ Resource createRelative(String relativePath) throws IOException; /** * Determine a filename for this resource, i.e. typically the last */ @Nullable String getFilename(); /** * Return a description for this resource, */ String getDescription();}复制代码

这些方法可以帮助我们查询资源状态、访问资源内容,甚至根据当前资源创建新的相对资源;

可以继承org.springframework.core.io.AbstractResource抽象类实现具体资源类。

ResourceLoader,“更广义的URL”

如何去查找和定位这些资源,该是 ResourceLoader 的职责所在。

ResourceLoader接口定义:

package org.springframework.core.io;public interface ResourceLoader {	/** Pseudo URL prefix for loading from the class path: "classpath:". */	String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;	/**	 * Return a Resource handle for the specified resource location.	 */	Resource getResource(String location);	/**	 * Expose the ClassLoader used by this ResourceLoader.	 */	@Nullable	ClassLoader getClassLoader();}复制代码

可用的 ResourceLoader

一、DefaultResourceLoader

ResourceLoader默认的实现类。

默认资源查找逻辑是:

  1. 以*classpath:*为前缀则返回ClassPathResource
  2. 尝试构造UrlResource,无资源则抛出MalformedURLException

二、FileSystemResourceLoader

继承自DefaultResourceLoader,但覆写了getResourceByPath(String)方法,使之从文件系统加载资源并以FileSystemResource类型返回。

ResourcePatternResolver——批量查找的 ResourceLoader

定义了Resource[] getResources(String locationPattern)方法用于批量加载Resource

public interface ResourcePatternResolver extends ResourceLoader {	/**	 * Pseudo URL prefix for all matching resources from the class path: "classpath*:"	 */	String CLASSPATH_ALL_URL_PREFIX = "classpath*:";	/**	 * Resolve the given location pattern into Resource objects.	 */	Resource[] getResources(String locationPattern) throws IOException;}复制代码

其主要实现类是PathMatchingResourcePatternResolver

PathMatchingResourcePatternResolver

该实现类支持ResourceLoader级别的资源加载,支持基于Ant风格的路径匹配模式(类似于 **/*.suffix之类的路径形式),支持ResourcePatternResolver新增加的classpath*:前缀等,基本上集所有技能于一身。

其构造方法如下:

public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {	/**	 * Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader.	 */	public PathMatchingResourcePatternResolver() {		this.resourceLoader = new DefaultResourceLoader();	}	/**	 * Create a new PathMatchingResourcePatternResolver.	 */	public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {		Assert.notNull(resourceLoader, "ResourceLoader must not be null");		this.resourceLoader = resourceLoader;	}	/**	 * Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader.	 */	public PathMatchingResourcePatternResolver(@Nullable ClassLoader classLoader) {		this.resourceLoader = new DefaultResourceLoader(classLoader);	}复制代码

其通过调用传入的或默认的ResourceLoader加载资源,故加载资源策略与其持有的ResourceLoader一致。

ApplicationContext 与 ResourceLoader

AbstractApplicationContext的子类的资源加载完全依托于内部持有的PathMatchingResourcePatternResolver来实现。

作为ResourceLoader或者ResourcePatternResolverApplicationContext有以下作用:

扮演ResourceLoader的角色

如下代码:

ResourceLoader resourceLoader = new ClassPathXmlApplicationContext("配置文件路径");// 或者        配置文件路径"); // ResourceLoader resourceLoader = new FileSystemXmlApplicationContext("        Resource fileResource = resourceLoader.getResource("D:/spring21site/README");        assertTrue(fileResource instanceof ClassPathResource);        assertFalse(fileResource.exists());        Resource urlResource2 = resourceLoader.getResource("http://www.spring21.cn");        assertTrue(urlResource2 instanceof UrlResource);复制代码

ResourceLoader类型的注入

通过对需要注入的bean实现ApplicationContextAware或者ResourceLoaderAware来依赖SpringAPI自动注入对应的对象,并且两者都使用ResourceLoader类型持有对象(不绝对)。

Resource类型的注入

如下代码:

public class XMailer {    private Resource template;    public Resource getTemplate() {        return template;    }    public void setTemplate(Resource template) {        this.template = template;    }}复制代码

如下配置:

...
复制代码

即可成功注入Resource类型对象。

其原理是: ApplicationContext 启动伊始,会通过一个org.springframework.beans.support.ResourceEditorRegistrar 来注册 Spring提供的针对Resource类型的PropertyEditor实现到容器中,这个PropertyEditor 叫做org.springframework.core.io.ResourceEditor 。这样,ApplicationContext 就可以正确地识别 Resource类型的依赖了。至于ResourceEditor怎么实现我就不用说了吧?你想啊,把配置文件中的路径让 ApplicationContext 作为 ResourceLoader给你定位一下不就得了。

I18n MessageSource

JavaSE的Locale与ResourceBundle

java.util.Locale

代表不同国家和地区,作用等同枚举。

Locale的三个构造方法:

Locale(String language)Locale(String language, String country)Locale(String language, String country, String variant)复制代码

java.util.ResourceBundle

用于保存多个Locale对应的资源,通常是properties保存的键值对。通过如下静态方法获取对应的ResourceBundle实例,进而获取对应参数。

public static final ResourceBundle getBundle(String baseName,Locale locale)复制代码

MessageSource与ApplicationContext

org.springframework.context.MessageSource

接口定义如下:

public interface MessageSource {	/**	 * Try to resolve the message. Return default message if no message was found.	 */	@Nullable	String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);	/**	 * Try to resolve the message. Treat as an error if the message can't be found.	 */	String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;	/**	 * Try to resolve the message using all the attributes contained within the	 * {
@code MessageSourceResolvable} argument that was passed in. */ String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;}复制代码

相对java原生,省略了获取ResourceBundle这一步骤。

实现了MessageSource的ApplicationContext

ApplicationContext将委派容器中一个名称为messageSourceMessageSource接口实现来完成MessageSource 应该完成的职责,故应作如下配置:

//    
messages
errorcodes
复制代码
可用的MessageSource

  1. StaticMessageSource可硬编码添加信息,多用于测试
  2. ResourceBundleMessageSource常用生产环境
  3. ReloadableResourceBundleMessageSource可定时更新资源

ApplicationContext内的messageSource三选一;或者可自己继承AbstractMessageSource实现定制化。

MessageSourceAware 和 MessageSource 的注入

实现MessageSourceAware接口,然后注册到ApplicationContext容器的bean将被注入MessageSource

也可直接通过XML配置注入:

messages
errorcodes
复制代码

容器内部事件发布

自定义事件发布

转载于:https://juejin.im/post/5c63df1fe51d457fa074ac47

你可能感兴趣的文章
vsftp 配置参数说明
查看>>
phpcms2008index.html当前位置导航phpcms全局变量搜索模块
查看>>
TangYuan使用教程-组合SQL服务标签
查看>>
Mac OS X下安装pyenv
查看>>
CentOS6.x 下 LNMP环境搭建(一、安装 MySQL)
查看>>
DNS中的递归查询与迭代查询
查看>>
NFS详解
查看>>
下载中心常见问题解答【Q&A帮助】
查看>>
教你怎么追一个女孩子,哥认为很有道理。
查看>>
索骥馆-网络营销之《锦囊妙计 网站推广101招 第7版》扫描版[PDF]
查看>>
我的友情链接
查看>>
Swift编程高级教程 变量与常量
查看>>
CCBPM 任务分配流程设计说明
查看>>
css 导航栏选中背景高亮显示
查看>>
[android]-记录日志到sd卡
查看>>
左图有文本,图片自由缩放
查看>>
错误:ERROR 1221 (HY000): Incorrect usage of DB GR...
查看>>
服务器性能测试之iperf,iozone,sysbench
查看>>
Linux终端查看
查看>>
安全高效的中小型网络
查看>>