Spring核心系列之ApplicationContext

栏目: Java · 发布时间: 8年前

内容简介:Spring核心系列之ApplicationContext

Hello,大家好,今天开始,小弟准备推出Spring系列的博客,希望大家喜欢。关于Spring其实我就不用再多介绍了,做过Web开发的,基本都使用Spring,包括现在比较时尚的Spring cloud微服务架构,其实也是基于Spring boot ,Spring boot 说到底其实还是传统的Spring三件套,只是避免了用户自己配置Bean,而是采用了自动配置,Spring boot后期有时间也专门给大家出一系列博客。这一期作为Spring的第一篇,先来点基础的,OK,来套路,文章结构:

  1. Spring中的Resource接口.
  2. BeanFactory和ApplicationContext
  3. WebApplicationContext

1. Spring中的Resource接口.

其实对于很多业务开发 程序员 来讲,这个接口是比较陌生的,大家知道的是在初始化容器的时候直接指定文件路径,然后容器就初始化好了,这个Resource接口是Spring提供的,它为应用提供了更强的底层资源访问能力。比JDK自带的File和URL类不知道强了多少。列下类结构:

Spring核心系列之ApplicationContext

说几个重点的: ClassPathResource: 以类路径为相对路劲下的资源 。 FileSystemResource : 以文件系统路径查找的资源。 ServletContextResource : 以相对于Web应用跟目录的方式访问。 ByteArrayResource: 二进制数组表示的资源。 比如现在Web的路径下又一个Spring的配置文件,我们可以这样加载:

Resource res =new ServletContectResource(/WEB-INF/classes/spring/application.xml);

看到代码,相信比较敏感的小伙伴应该感觉到了,这种加载方式显然是不合适的,因为在使用不同的资源类型时,必须使用相应的Resource资源类,这是比较麻烦的,是否可以在不现实使用Resource实现类的情况下,仅通过资源地址的特殊标识就可以访问相应的资源呢?Spring这么伟大的框架,当然是可以的。 Spring不仅能够通过"classpath:","file"等资源地址前缀识别不同资源类型,还支持Ant风格带通配符的资源地址。Spring内部会通过资源加载器来根据不同的资源路径选择相应的Resource实现类。避免的使用者自己选择实现类。

1.1 资源地址表达式

先看下Spring内置的一些资源前缀表达的含义:

Spring核心系列之ApplicationContext

然后Ant风格:

  • ?:匹配文件名中的一个字符.
  • *:匹配文件命中的任意字符.
  • ** :匹配多层路径.

具体就不举例子了,Ant风格的通配符太常用了。

1.2 资源加载器

Spring核心系列之ApplicationContext

这些接口我就不多讲了,没什么实际意义,只说一个,PathMatchingResourcePatternResolver,这个是Spring提供的标准资源加载器,能够支持Ant风格的资源路径,并根据不同前缀类型返回相应的Resource.举个栗子:

public class GaoshiApplication {

	public static void main(String[] args) throws IOException {

		PathMatchingResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
		Resource[] res =resolver.getResources("file:/Users/zdy/Desktop/sql.txt");
		for (Resource  resource : res){
			System.out.println(resource.getDescription()+"----"+resource.getFilename());
		}
		SpringApplication.run(GaoshiApplication.class, args);
	}
}
输出结果:
URL [file:/Users/zdy/Desktop/sql.txt]----sql.txt

好了,其实这一小节为什么要给大家讲Resource和PathMatchingResourcePatternResolver资源加载器呢,很多人可能感觉没什么用,反正Spring内部自己使用就完了,跟我没关系。其实不是的,老铁们,Spring内部自己使用不假,首先,知道点底层原理不好吗?其次, 大家如果自己有配置文件在classpath下,然后想通过代码去加载(虽然这种需求非常少),那么大家就可以自己使用Spring提供的资源加载器了。这个加载器还是很方便的,直接根据前缀加载资源,而且还支持Ant通配符。你说厉害不厉害。

2. BeanFactory和ApplicationContext

2.1 BeanFactory

BeanFactory,其实很多人听过,只是没有用过,大家启动容器的时候可能都是用的ApplicationContext的某个实现类,所以这个BeanFactory慢慢的都淡了,更别说它的实现类了。说下特性:

  1. BeanFactory是延迟加载,如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常;而ApplicationContext则在初始化自身是检验,这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用ApplicationContext。
  2. ApplicationContext继承自BeanFactory,提供的功能更加强大,一般情况下都是使用ApplicationContext

然后举个初始化BeanFactory的例子吧:

//调用资源加载器加载Spring配置文件
		PathMatchingResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
		Resource res =resolver.getResource("classpath:/application.xml");
		
		//创建默认Spring提供的BeanFactory实现类
		DefaultListableBeanFactory bf =new DefaultListableBeanFactory();
		
		//BeanDefinition 读取器,专门读取资源到容器
		XmlBeanDefinitionReader reader =new XmlBeanDefinitionReader(bf);
		
		//读取资源进到容器 
		reader.loadBeanDefinitions(res);
		
		//此时容器初始化完毕后可以取里面的bean了.
		bf.getBean("...");

可以看到,代码比较繁琐,而且很啰嗦。BeanFactory的功能还比较弱,所以大家就当了解吧。

2.2 ApplicationContext

这个ApplicationContext其实就是老铁们经常说的Spring容器了。因为相对要重要一些,所以列了大致的类继承图:

Spring核心系列之ApplicationContext

说下图中几个重要的类或接口:

  • ApplicationEventPublisher: 让容器拥有发布应用程序上下文事件的功能.
  • ResourcePatternResolver:实现了类似于资源加载器的功能,能够识别特定前缀加Ant风格的路径并加载到容器中.
  • LifeCycle:管理容器中bean的生命周期。
  • ConfigurableApplicationContext:主要新增了refresh()和close()方法,让ApplicationContext有用了启动,关系和刷新上下文的功能。
  • ClassPathXmlApplicationContext与FileSystemXmlApplicationContext :Spring提供的两个常用的ApplicationContext实现类,前者默认从类路径加载配置文件,后者从文件系统加载。 然后初始化一个ApplicationContext看看:
ApplicationContext ac =new ClassPathXmlApplicationContext("application.xml");
ApplicationContext ac =new FileSystemXmlApplicationContext(/User/Desktop/application.xml);

ClassPathXmlApplicationContext如果没有前缀默认就是classpath: FileSystemXmlApplicationContext如果没有前缀默认就是 file:

然后再说一个,Spring容器不仅可以通过xml文件来初始化,@Configuration注解大家应该知道,也是注册Bean用的,当然了,Spring也提供了相应的AnnotationConfigApplicationContext.

ApplicationContext context =new AnnotationConfigApplicationContext(Config.class);

Config类就是我们加了@Configuration的类了。

3. WebApplicationContext

其实WebApplicationContext也属于ApplicationContext,为什么单独拿出来讲呢,因为比较重要。WebApplicationContext是Spring专门为Web应用准备的。它允许从相对于Web根目录的路径中装载配置文件完成初始化工作。 WebApplicationContext与ServletContext可以相互获得 .在非Web应用的环境下,Bean只有singleton和prototype两种作用域,而WebApplicationContext为Bean添加了三个新的作用域:request,session,global session。来看下类继承图:

Spring核心系列之ApplicationContext
最最核心的XmlWebApplicationContext和AnnotationConfigWebApplicationContext,大家猜都应该猜到了,一个是XML配置的,一个是@Configuration配置的。

然后说下WebApplicationContext和ServletContext是如何相互获取的,其实很简单, 在WebApplicationContext里有ServletContext成员变量,直接get就完了。在ServletContext里有一个写死的attrbute,也是直接get..而且Spring提供了一个WebApplicationContextUtils来封装了这个写死的attribute.

其实就是直接调用了ServletContext.getAttribute(ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
    public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
        return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
    }
Spring核心系列之ApplicationContext

然后说下WebApplication的初始化,做过Web的都知道,其实要么在Web.xml里面配置一个ContextLoaderListener,要么配置一个自启动的LoaderServlet.其实比较简单了,我展示下ContextLoaderListener.

<!-- 加载spring容器 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/applicationContext-*.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

如果不是根据xml文件启动Spring容器而是根据@Configuration类启动,其实也很简单.

<context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
  </context-param>
  <!-- 加载spring容器 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>com.zdy.Configuration</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

配置一个contextClass参数ApplicationContext改为AnnotationConfigWebApplicationContext,然后contextConfigLocation不是指定配置文件xml位置了,改为指定Configuration类的位置。就OK了。

最后,需要强调的是, 由于Spring容器自带的Log4j功能,所以用户可以直接将Log4j的配置文件放置在类路径下,直接就生效了 ,但是,如果不在类路径下,需要在Web.xml中手动指定文件的位置和启动log4j的listener,这里我就不演示了,需要注意的是,这个log4j的listener或者servlet必须在spring容器的listenier或servlet前面。不要问为什么。就是这么规定的。不过这点大家不常用,所以我只是提一提。

结语

好了,其实大家也看出来了,讲Spring的时候我还是偏向于使用的,Spring的底层深层次的原理其实设计到的不多。Spring这个至尊框架,我觉得先要宏观使用上先整明白。后期有机会给大家多讲点底层实现。喜欢大家多关注接下来的Spring系列文章。 Over,Have a good day .


以上所述就是小编给大家介绍的《Spring核心系列之ApplicationContext》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

An Introduction to Genetic Algorithms

An Introduction to Genetic Algorithms

Melanie Mitchell / MIT Press / 1998-2-6 / USD 45.00

Genetic algorithms have been used in science and engineering as adaptive algorithms for solving practical problems and as computational models of natural evolutionary systems. This brief, accessible i......一起来看看 《An Introduction to Genetic Algorithms》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具