zoukankan      html  css  js  c++  java
  • 转: 彻底理解 Spring 容器和应用上下文

    本文由 简悦 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">


            
        
        

    然后通过应用上下文将配置加载到 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)
  • 相关阅读:
    机器学习中的度量——其他度量
    机器学习中的度量——相似度
    机器学习中的度量——相关系数
    机器学习中的度量——统计上的距离
    redis数据结构和常用命令
    分布式一致性算法梳理
    zookeeper集群搭建及ZAB协议
    手写RPC框架(netty+zookeeper)
    zookerper入门、核心概念和使用场景
    RabbitMQ集群部署、高可用和持久化
  • 原文地址:https://www.cnblogs.com/xmanblue/p/11044092.html
Copyright © 2011-2022 走看看