内容简介:Spring核心系列之ApplicationContext
Hello,大家好,今天开始,小弟准备推出Spring系列的博客,希望大家喜欢。关于Spring其实我就不用再多介绍了,做过Web开发的,基本都使用Spring,包括现在比较时尚的Spring cloud微服务架构,其实也是基于Spring boot ,Spring boot 说到底其实还是传统的Spring三件套,只是避免了用户自己配置Bean,而是采用了自动配置,Spring boot后期有时间也专门给大家出一系列博客。这一期作为Spring的第一篇,先来点基础的,OK,来套路,文章结构:
- Spring中的Resource接口.
- BeanFactory和ApplicationContext
- WebApplicationContext
1. Spring中的Resource接口.
其实对于很多业务开发 程序员 来讲,这个接口是比较陌生的,大家知道的是在初始化容器的时候直接指定文件路径,然后容器就初始化好了,这个Resource接口是Spring提供的,它为应用提供了更强的底层资源访问能力。比JDK自带的File和URL类不知道强了多少。列下类结构:
说几个重点的: 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内置的一些资源前缀表达的含义:
然后Ant风格:
- ?:匹配文件名中的一个字符.
- *:匹配文件命中的任意字符.
- ** :匹配多层路径.
具体就不举例子了,Ant风格的通配符太常用了。
1.2 资源加载器
这些接口我就不多讲了,没什么实际意义,只说一个,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慢慢的都淡了,更别说它的实现类了。说下特性:
- BeanFactory是延迟加载,如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常;而ApplicationContext则在初始化自身是检验,这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用ApplicationContext。
- 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容器了。因为相对要重要一些,所以列了大致的类继承图:
说下图中几个重要的类或接口:
- 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。来看下类继承图:
最最核心的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); }
然后说下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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- CSS核心技术详解-核心概念
- WTC测评:核心团队从业经验,核心代码尚未开源
- AI 产品开发的核心原则:以研究为核心驱动
- Knative 核心概念介绍:Build、Serving 和 Eventing 三大核心组件
- 区块链技术六大核心算法,读懂六大核心算法就变成区块链专家
- webpack怎么能只是会用呢,核心中的核心tapable了解下?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
流畅的Python
[巴西] Luciano Ramalho / 安道、吴珂 / 人民邮电出版社 / 2017-5-15 / 139元
【技术大咖推荐】 “很荣幸担任这本优秀图书的技术审校。这本书能帮助很多中级Python程序员掌握这门语言,我也从中学到了相当多的知识!”——Alex Martelli,Python软件基金会成员 “对于想要扩充知识的中级和高级Python程序员来说,这本书是充满了实用编程技巧的宝藏。”——Daniel Greenfeld和Audrey Roy Greenfeld,Two Scoops ......一起来看看 《流畅的Python》 这本书的介绍吧!
XML 在线格式化
在线 XML 格式化压缩工具
RGB CMYK 转换工具
RGB CMYK 互转工具