本文由 简悦 SimpRead 转码, 原文地址 https://mp.weixin.qq.com/s/o11jVTJRsBi998WlgpfrOw

有了 Spring 之后,通过依赖注入的方式,我们的业务代码不用自己管理关联对象的生命周期。业务代码只需要按照业务本身的流程,走啊走啊,走到哪里,需要另外的对象来协助了,就给 Spring 说,我想要个对象——于是 Spring 就很贴心的给你个对象。

听起来似乎很简单,使用起来也不难,但是如果仅仅是这样的拿来主义,倒也洒脱,不用费什么脑子。。。可是,你就真的不关心,Spring 是从哪里把对象给你的吗?

如果你想要了解 Spring 深一些,而不仅仅是拿来用用,那么你就应该好好思考一下上诉问题,不然,这篇博文你还看个铲铲啊。。。

你可以这样去思考:Spring 既然要负责应用程序中那么多对象的创建管理,就像苹果要生产那么多的手机(对象)一样,肯定有一个专门搞对象的地方。苹果生产手机的地方叫工厂,比如富士康,但放在软件开发中,对于 Spring 搞对象的地方我们就不叫工厂了,而叫做容器。

是的,容器的概念在 java 中你最熟悉的莫过于 Tomcat 了,它正是一个运行 Servlet 的 web 容器,而 Spring 要想实现依赖注入功能,就离不开对象生产的容器——如果没有容器负责对象的创建管理,你的程序代码只是喊要对象了,Spring 也无处给你啊。

实际上,容器是 Spring 框架实现功能的核心,容器不只是帮我们创建了对象那么简单,它负责了对象整个的生命周期的管理——创建、装配、销毁。

关于 Spring 的这个容器你最常听闻的一个术语就是 IOC 容器。所谓 IOC,是一种叫控制反转的编程思想,网上有很通俗易懂的总结,我就不胡乱阐述了。总之一句话,我的应用程序里不用再过问对象的创建和管理对象之间的依赖关系了,都让 IOC 容器给代劳吧,也就是说,我把对象创建、管理的控制权都交给 Spring 容器, 这是一种控制权的反转,所以 Spring 容器才能称为 IOC 容器。

不过这里要厘清一点:并不是说只有 Spring 的容器才叫 IOC 容器,基于 IOC 容器的框架还有很多,并不是 Spring 特有的。

好了,终于把 Spring 的容器概念阐述的差不多了,但有什么卵用呢?光有容器你其实什么都干不了!你以为容器那么科幻,跟叮当猫面前的百宝袋一样,你想要啥它就给你啥?

实际上,容器里面什么都没有,决定容器里面放什么对象的是我们自己,决定对象之间的依赖关系的,也是我们自己,容器只是给我们提供一个管理对象的空间而已。那么,我们怎么向容器中放入我们需要容器代为管理的对象呢?这就涉及到 Spring 的应用上下文了。

什么是应用上下文呢,你可以简单的理解成就是将你需要 Spring 帮你管理的对象放入容器的那么一种。。一种。。额。。一种容器对象——是的,应用上下文即是 Spring 容器的一种抽象化表述;而我们常见的 ApplicationContext 本质上说就是一个维护 Bean 定义以及对象之间协作关系的高级接口。额,听起来是不是很抽象拗口?那你再读一遍呢。。。

这里,我们必须明确,Spring 的核心是容器,而容器并不唯一,框架本身就提供了很多个容器的实现,大概分为两种类型:一种是不常用的 BeanFactory,这是最简单的容器,只能提供基本的 DI 功能;还有一种就是继承了 BeanFactory 后派生而来的应用上下文,其抽象接口也就是我们上面提到的的 ApplicationContext,它能提供更多企业级的服务,例如解析配置文本信息等等,这也是应用上下文实例对象最常见的应用场景。

有了上下文对象,我们就能向容器注册需要 Spring 管理的对象了。对于上下文抽象接口,Spring 也为我们提供了多种类型的容器实现,供我们在不同的应用场景选择:

① AnnotationConfigApplicationContext: 从一个或多个基于 java 的配置类中加载上下文定义,适用于 java 注解的方式;

② ClassPathXmlApplicationContext: 从类路径下的一个或多个 xml 配置文件中加载上下文定义,适用于 xml 配置的方式;

③ FileSystemXmlApplicationContext: 从文件系统下的一个或多个 xml 配置文件中加载上下文定义,也就是说系统盘符中加载 xml 配置文件;

④ AnnotationConfigWebApplicationContext: 专门为 web 应用准备的,适用于注解方式;

⑤ XmlWebApplicationContext: 从 web 应用下的一个或多个 xml 配置文件加载上下文定义,适用于 xml 配置方式。

有了以上理解,问题就很好办了。你只要将你需要 IOC 容器替你管理的对象基于 xml 也罢,java 注解也好,总之你要将需要管理的对象(Spring 中我们都称之问 bean)、bean 之间的协作关系配置好,然后利用应用上下文对象加载进我们的 Spring 容器,容器就能为你的程序提供你想要的对象管理服务了。

下面,还是贴一下简单的应用上下文的应用实例:

我们先采用 xml 配置的方式配置 bean 和建立 bean 之间的协作关系:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans

           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

    <bean id="man" class="spring.chapter1.domain.Man">
        <constructor-arg ref="qqCar" />
    
    <bean  id="qqCar" class="spring.chapter1.domain.QQCar"/>

然后通过应用上下文将配置加载到 IOC 容器,让 Spring 替我们管理对象,待我们需要使用对象的时候,再从容器中获取 bean 就 ok 了:

public class Test {
    public static void main(String[] args) {

        // 加载项目中的 spring 配置文件到容器

//        ApplicationContext context = new ClassPathXmlApplicationContext("resouces/applicationContext.xml");
        // 加载系统盘中的配置文件到容器
        ApplicationContext context = new FileSystemXmlApplicationContext("E:/Spring/applicationContext.xml");
        // 从容器中获取对象实例
        Man man = context.getBean(Man.class);
        man.driveCar();
    }

}

以上测试中,我将配置文件 applicationContext.xml 分别放在项目中和任意的系统盘符下,我只需要使用相应的上下文对象去加载配置文件,最后的结果是完全一样的。

当然,现在项目中越来越多的使用 java 注解,所以注解的方式必不可少:

// 同 xml 一样描述 bean 以及 bean 之间的依赖关系
@Configuration
public class ManConfig {
    @Bean
    public Man man() {
        return new Man(car());
    }
    @Bean
    public Car car() {
        return new QQCar();
    }
}
public class Test {
    public static void main(String[] args) {
        // 从 java 注解的配置中加载配置到容器
        ApplicationContext context = new AnnotationConfigApplicationContext(ManConfig.class);
        // 从容器中获取对象实例
        Man man = context.getBean(Man.class);
        man.driveCar();
    }
}

自此,Spring 容器和应用上下文就算阐述的差不多了,具体的技能点在今后的博文中会慢慢的给大家奉上。

原文链接:www.cnblogs.com/chenbenbuyi

****推荐程序员必备微信号 ****

**程序员内参**
微信号:

programmer0001

**推荐理由:**

在这里,我们分享程序员相关技术,职场生活,行业热点资讯。不定期还会分享 IT 趣文和趣图。这里属于我们程序员自己的生活,工作和娱乐空间。

 ▼长按下方↓↓↓二维码识别关注
![](https://mmbiz.qpic.cn/mmbiz_jpg/jNmCBexQlC7grRGuAvlTrQKGNVEu7zySj3P6YxicNaicwVnweAeV6ROWsp10kHYj0jn7EhRBbQa60gzHYmloVXkw/640?wx_fmt=jpeg)

转: 彻底理解 Spring 容器和应用上下文的更多相关文章

  1. 资深程序员总结:彻底理解Spring容器和应用上下文

    点关注,不迷路:持续更新Java架构相关技术及资讯热文!!! 有了Spring之后,通过依赖注入的方式,我们的业务代码不用自己管理关联对象的生命周期.业务代码只需要按照业务本身的流程,走啊走啊,走到哪 ...

  2. Spring基础篇——Spring容器和应用上下文理解

    上文说到,有了Spring之后,通过依赖注入的方式,我们的业务代码不用自己管理关联对象的生命周期.业务代码只需要按照业务本身的流程,走啊走啊,走到哪里,需要另外的对象来协助了,就给Spring说,我想 ...

  3. 通过单元测试理解spring容器以及dubbo+zookeeper单元测试异常处理

    一.先说一个结论:单元测试与主项目的spring容器是隔离的,也就是说,单元测试无法访问主项目spring容器,需要自己加载spring容器. 接下来是代码实例,WEB主项目出于运行状态,单元测试中可 ...

  4. 理解Spring 容器、BeanFactory 以及 ApplicationContext

    一.spring 容器理解 spring 容器可以理解为生产对象(Object)的地方,在这里容器不只是帮助我们创建对象那么简单,它负责了对象的整个生命周期-创建.装配.销毁.而这里对象的创建管理的控 ...

  5. 深入理解 spring 容器,源码分析加载过程

    Spring框架提供了构建Web应用程序的全功能MVC模块,叫Spring MVC,通过Spring Core+Spring MVC即可搭建一套稳定的Java Web项目.本文通过Spring MVC ...

  6. Spring容器、BeanFactory和ApplicationContext,及3种装配Bean的方式

    目录 一. spring容器理解 二. BeanFactory和ApplicationContext之间的关系 三. BeanFactory详情介绍 四.ApplicationContext介绍 五. ...

  7. 深入理解Spring事件机制(一):广播器与监听器的初始化

    前言 Spring 从 3.x 开始支持事件机制.在 Spring 的事件机制中,我们可以令一个事件类继承 ApplicationEvent 类,然后将实现了 ApplicationListener ...

  8. 深入理解Spring的容器内事件发布监听机制

    目录 1. 什么是事件监听机制 2. JDK中对事件监听机制的支持 2.1 基于JDK实现对任务执行结果的监听 3.Spring容器对事件监听机制的支持 3.1 基于Spring实现对任务执行结果的监 ...

  9. spring容器和上下文的理解

    spring容器和上下文的理解 spring框架现在使用的很多,这说明有其独特之处----依赖注入,很简单的四个字,在我们需要对象的时候,spring就可以给我们提供所需要的对象,对象的创建.销毁.管 ...

随机推荐

  1. shell编程基本语法和变量

    一.编写shell脚本基本格式 拿最简单的hello word举例 .#!/bin/bash echo 'hello world' .#!/bin/bash:告诉计算机,使用bash解释器来执行代码 ...

  2. Appium 自动化测试配置wda的两种方式。

    tips:WebDriverAgent是Appium1.6.3以后版本新添加的模块,为了让appium与iPhone(基于xcuitest)设备进行通信而添加的.但是,这个模块在是一个独立的项目,在使 ...

  3. Qt播放音视频文件报错DirectShowPlayerService::doRender: Unresolved error code 0x80040266或DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x80004005 ()

    使用QMediaPlayer和QVideoWidget QHBoxLayout *m_layout=newQHBoxLayout(this); QMediaPlayer *m_player = new ...

  4. hexo笔记

    目录 hexo 常用指令 站内文章跳转 hexo安装 NexT主题 默认主题 评论插件-gitalk 修改内容区宽度 添加文章阴影 文章摘要设置 一篇文章多个 categories hexo的一些配置 ...

  5. 201777010217-金云馨《面向对象程序设计(java)》第十三周学习

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  6. 201871010135 张玉晶《面向对象程序设计(java)》第十六周学习总结

    第一部分:总结教材14.1-14.3知识内容 并发 • 线程的概念 • 中断线程 • 线程状态 • 多线程调度 • 线程同步 一.线程的概念 1. 程序是一段静态的代码,它是应用程序执行的蓝本. 2. ...

  7. 10-numpy笔记-np.random.randint

    b_idx = np.random.randint(0, 9, 90) >>> b_idx array([0, 1, 5, 4, 7, 2, 7, 0, 0, 4, 2, 2, 3, ...

  8. 神兽、佛祖保佑,代码全程无bug

    ''' ━━━━━━神兽出没━━━━━━ ┏┓ ┏┓ ┏┛┻━━━━━┛┻┓ ┃ ┃ ┃ ━ ┃ ┃ ┳┛ ┗┳ ┃ ┃ ┃ ┃ ┻ ┃ ┃ ┃ ┗━┓ ┏━┛ Code is far away fr ...

  9. 本地jar包在maven工程中pom引用

    背景   在使用Maven的过程中,经常碰到有些jar包在中央仓库没有的情况.如果公司有私服,那么就把jar包安装到私服上.如果没有私服,那就把jar包安装到本地Maven仓库.下面是如何把jar包导 ...

  10. zz扔掉anchor!真正的CenterNet——Objects as Points论文解读

    首发于深度学习那些事 已关注写文章   扔掉anchor!真正的CenterNet——Objects as Points论文解读 OLDPAN 不明觉厉的人工智障程序员 ​关注他 JustDoIT 等 ...