在你学习Spring之前,你肯定听说过“控制反转”、“依赖注入”、“上下文”等名词,伴随着这些名词的,是一些冗长晦涩的解释,这些解释并没有什么显著的错误,但是因为太过抽象导致初学者们无法直观地去理解它们。

废话不多说,我们通过举例或者写代码来一步一步理解它们。

在一个系统里,可能有多个业务部分,比如用户服务,订单服务,数据服务等等,在代码里,这些服务也许分布在多个类中,可能叫做UserService或者OrderService等等。为了简便,我们假设系统里有A、B、C、D四个类,他们有如下的依赖关系:

简单来说,D是B的成员,A和B是C的成员。以前Spring这种东西没有出现的时候,你可能手动地去创建ABCD对象,再设置他们的依赖关系,如下图:

上面的代码看起来很简单,也不复杂。问题是当你的系统规模扩大了以后,有上百个对象需要初始化以及设置依赖的时候,复杂度就直线上升了。

系统类的对象越多,依赖关系越复杂

为了降低复杂度,减少他们之间的耦合,这个时候我们就需要用上Spring容器了。程序里的对象都可以扔到容器里,对象只需要告诉容器它需要哪些依赖就行,容器自动初始化好并给它。比如上面ABCD那个例子,C告诉容器它需要A和B,B告诉容器它需要D,这样ABCD四个对象都可以扔到容器里了,当你想用C的时候,就从容器里面拿出来,这时候C的成员就已经包含了A和B了(我们目前只讨论单例的情况,就是一个类只有一个对象)。

容器通过“配置”来了解对象之间的依赖关系。

在Spring框架里,ApplicationContext就代表了容器(又叫应用程序上下文),容器里的对象,又叫Bean。配置有两种方式,一种是xml,一种是Java配置(或者说代码配置)。早些年的时候,Java Web(SSH)开发为人诟病的,就是臃肿的xml配置,虽然目前Spring仍然支持xml配置和混合配置,不过Spring Boot已经建议使用Java配置了。我们来通过一个例子来看看如何使用容器和配置:

图中显示了项目的源码结构、程序的入口、配置以及依赖。

上图写出了ABCD的源码。

配置文件是Config.java,它有一个@Configuration注解,这表明Config类是配置类。它还有另外一个注解@ComponentScan,这个注解表示容器应该去扫描程序的代码,看看那些组件应当被初始化为Bean。哪些类会被初始化为Bean呢?我们看看ABCD的源码,发现他们各自都有注解@Component,这个注解就表示了它所在的类是组件,需要初始化Bean。C和B的成员变量都用@Autowired注解来修饰,这样容器就知道他们都依赖哪些Bean了,ABCD的对象都生成好之后,容器就把D对象赋值给B的成员,把A和B的对象赋值给C的成员。

如果你运行程序,会发现输出的结果是true,也就是C里的A成员不为空。这样你是不是就理解了Spring容器的作用了呢?你的程序不必再在ABCD的外部去设置他们的依赖了,反而只需要在ABCD的类的内部指明依赖就行,这个从外而内的过程就是控制反转(IoC,Inversion of Control),控制权交给了Spring容器,Spring容器也叫IoC容器。你还可能听过依赖注入(DI,Dependency Injection),如果你看网上文章没明白,权当他们是一样的好了。

对于开源库,他们的类肯定没有@Component注解,这样肯定不能通过扫描来加入容器。那就需要写点代码了。Config类中有一个objectMapper方法,返回了一个ObjectMapper对象(ObjectMapper是Jackson的关键类),objectMapper方法有个@Bean注解,表示返回的对象会加入到容器中。ObjectMapper对象可以在objectMapper方法里,进行一些修改呀,配置呀等等。

这个时候ObjectMapper对象还没人用,如果ABCD任何一个类想用,只需要在类中加一个成员@Autowired ObjectMapper objectmapper;,Spring容器会自动把ObjectMapper对象赋值到这个成员上。非常方便,尤其是在大项目里,类非常多,一行代码就把你需要的对象拿过来用,简直爽的不行。在实践中,依赖的类常常是个接口,使用者只调用接口就行,至于容器给它哪种实现并不重要,这个逻辑在“配置”里就可以控制。这样,程序的耦合度进一步减小了。

在我们之前运行第一个Spring Boot应用的时候,我们曾经添加了一个控制器,他有个@Controller注解,这个注解相当于一个特殊的@Component,只不过@Controller表示当前的组件是用来处理网络请求的。类似的还有,@Service用来表示业务相关的组件,@Repository用来表示数据获取相关的组件。他们都是通过自动扫描放到Spring容器中的。

总结

为了让大家理解Spring容器,本文忽略了很多技术上的细节,比如Bean的命名,比如说@ComponentScan的扫描路径和注解参数,比如声明依赖除了在成员上加@Autowired以外还能通过构造方法或者setter等等。我相信你懂了Spring容器的概念之后,这些都不是什么问题。

博客链接:fookwood.com/spring-boot…

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

Spring Boot教程(7) – 直观地理解Spring容器相关推荐

  1. Spring Boot 教程(三): Spring Boot 整合Mybatis

    教程简介 本项目内容为Spring Boot教程样例.目的是通过学习本系列教程,读者可以从0到1掌握spring boot的知识,并且可以运用到项目中.如您觉得该项目对您有用,欢迎点击收藏和点赞按钮, ...

  2. 准备写个Spring Boot教程

    最近我打算写一系列Spring Boot教程,用来讲解Spring Boot基础知识和一些常见的应用场景.你可能会问,现在讲这个话题的东西这么多,写出来的意义是啥,别人会看么.我的觉得吧,一条街上很多 ...

  3. Spring Boot教程(十六):Spring Boot集成shiro

    Apache Shiro™是一个功能强大且易于使用的Java安全框架,可执行身份验证,授权,加密和会话管理.借助Shiro易于理解的API,您可以快速轻松地保护任何应用程序 - 从最小的移动应用程序到 ...

  4. Spring Boot教程

    Spring Boot教程 欢迎使用Spring Boot教程.Spring Boot是Pivotal Team(The Spring Team)的一个全新项目.它是在现有Spring Framewo ...

  5. 超详细的Spring Boot教程,搞定面试官!

    前言 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置 ...

  6. 【Spring Boot官方文档原文理解翻译-持续更新中】

    [Spring Boot官方文档原文理解翻译-持续更新中] 文章目录 [Spring Boot官方文档原文理解翻译-持续更新中] Chapter 4. Getting Started 4.1. Int ...

  7. Spring Boot教程(二十):Spring Boot使用String Task定时任务

    一.JAVA常见的几种定时任务比较 Timer:jdk自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让程序按照某一个频度执行, ...

  8. Spring Boot教程系列(ImportNew )

    ImportNew Spring Boot教程系列 SpringBoot (一) :入门篇--http://mp.weixin.qq.com/s/hAJmvrYfS6OehMYVgqpqkw Spri ...

  9. Spring Boot教程系列 ImportNew

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Impo ...

最新文章

  1. Keil错误fatal error: UTF-16 (LE) byte order mark detected
  2. hoj 3005 Game Rigging 强联通分量求缩点
  3. MapReduce基础开发之五分布式下载ftp文件到本地再迁移到hdfs
  4. 分布式系统——网络监视系统zabbix3.4.2,以及向zabbix中添加被监视主机(一)
  5. java线程池应用的好处_java高级应用:线程池全面解析
  6. [渗透攻防] 二.SQL MAP工具从零解读数据库及基础用法
  7. VSCode+BeetleX.VueHost开发Vue应用
  8. Loj#6053-简单的函数【Min25筛】
  9. 博客url什么形式_URL的完整形式是什么?
  10. 漫画:什么是一致性哈希?
  11. 糙哥、糙姐:指为了解决问题,随意调整参数的程序员
  12. c语言累加和校验_累加和校验算法(CheckSum算法)
  13. flash builder编译报错
  14. dell 2420 bios 降级文件,可以用回独立显卡
  15. 记一次应急-插U盘之后文件夹全变成exe中毒(100%解决)
  16. 【 开源计划 - Flutter组件 】 星星也可以如此闪耀 flutter_star
  17. 学习Java的心路历程
  18. 即时聊天工具混战中国
  19. 《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
  20. python six模块升级方法

热门文章

  1. 谈谈CTO、技术总监、首席架构师的区别
  2. 成都Uber优步司机奖励政策(3月9日)
  3. 我们离DevOps有多远--持续集成思想的延伸
  4. [摘自MSDN] ASP.Net2.0学习 [1] 母版页 2 : 创建和使用 ASP.NET 母版页
  5. 数据湖三种方案的流行度调查
  6. springboot在intellij中的热部署(Hot swapping)配置
  7. 半监督训练-思想与代码实践
  8. 消除ubuntu16.04自带的alt快捷键
  9. 无限循环小数转化为分数形式
  10. 【机器学习】支持向量机面试知识点小结