IoC—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,IoC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接创建。它能指导我们如何设计出松耦合、更优良的程序。
用图例说明一下,传统程序设计如图1-1,都是主动去创建相关对象然后再组合起来:
当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图1-2所示:
DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:
IoC和DI是什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
什么是容器?
在每个框架中都有一个容器的概念,所谓的容器就是将常用的服务封装起来,然后,用户只需要遵循一定的规则,就可以达到统一、灵活、安全、方便、快速的目的。具有依赖注入功能的容器,负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
Bean是什么?
由IoC容器管理的那些组成应用程序的对象就叫Bean。Bean就是由Spring容器初始化、装配及管理的对象,除此之外,Bean就与应用程序中的其他对象没什么区别了。
元数据 BeanDefinition
确定如何实例化Bean、管理Bean之间的依赖关系及管理Bean,就需要配置元数据,在Spring中由BeanDefintion代表。
IoC容器如何工作(以XML配置方式解释)?
IoC容器其实就是一个大工厂,它用来管理我们所有的对象以及依赖关系。
BeanFactory是spring的原始接口,针对原始结构的实现类功能比较单一,BeanFactory接口实现的容器,特点是在每次获取对象时才会创建对象。
BeanFactory的继承体系:
ApplicationContext继承了BeanFactory接口,拥有BeanFactory的全部功能,并且扩展了很多高级特性,每次容器启动时就会创建所有的对象。
ApplicationContext的继承体系:
创建ApplicationContext的方法:
其中在ApplicationContext子类中有一个比较重要的:WebApplicationContext,是专门为Web应用准备的。
Web应用与Spring融合:
我们看看BeanFactory的生命周期:
接下来我们再看看ApplicationContext的生命周期:
初始化的过程都是比较长,我们可以分类来对其进行解析:
ApplicationContext和BeanFactory不同之处在于:
有了上面的知识点了,我们再来详细地看看Bean的初始化过程:
简要总结:
两者装载bean的区别
用BeanFactory还是ApplicationContent?
建议web应用,在启动的时候就把所有的Bean都加载了。(把费时的操作放到系统启动中完成) 。
Bean 工厂(com.springframework.beans.factory.BeanFactory)是Spring 框架最核心的接口,它提供了高级IoC 的配置机制。
应用上下文(com.springframework.context.ApplicationContext)建立在BeanFactory 基础之上。
几乎所有的应用场合我们都直接使用ApplicationContext 而非底层的BeanFactory。
装配的方式
Spring4.x开始IoC容器装配Bean有4种方式:
总的来说:我们以Xml配置+注解来装配Bean居多,其中注解这种方式占大部分!
依赖注入方式
依赖注入的方式有3种方式:
总的来说使用属性注入是比较灵活和方便的,这是大多数人的选择!
对象之间的关系
Bean的作用域
使用到了Web应用环境相关的Bean作用域的话,是需要我们手动配置代理的~
原因也很简单:因为我们默认的Bean是单例的,为了适配Web应用环境相关的Bean作用域--->每个request都需要一个对象,此时我们返回一个代理对象出去就可以完成我们的需求了!
处理自动装配的歧义性
一个接口两个实现类,怎么在注入的时候优先调用某个实现类?
可以归纳成两种解决方案:
1、使用@Primary注解设置为首选的注入Bean
2、使用@Qualifier注解设置特定名称的Bean来限定注入,也可以使用自定义的注解来标识。
装配bean总结
分别应用的场景:
实例化bean的两种方式
1、调用无参构造方法
当personDaoImpl被实例化后,给property标签所指定的属性进行赋值,赋值也称注入。
2、调用有参构造方法
调用有参构造方法,第一个参是int类型,第二个参数String的构造方法进行初始化。
非基本类型和String类型属性注入
ref 注入的是对象。ref的值是spring容器中的key
叶文龙
陈白
赵青
com.mysql.jdbc.Driver
jdbc:mysql:///aaa
root
123456
北京
天津
上海
什么是spring?
Spring是个java企业级应用的开源开发框架。Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用。Spring框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯。
使用Spring框架的好处是什么?
Spring由哪些模块组成?
简单可以分成6大模块:
BeanFactory 实现举例
Bean工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从真正的应用代码中分离。
XmlBeanDefinitionReader和DefaultListableBeanFactory。
什么是Spring的依赖注入?
依赖注入,是IoC的一个方面,说的是你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IoC容器)负责把他们组装起来。
有哪些不同类型的IoC(依赖注入)方式?
什么是Spring beans?
Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中
有四种重要的方法给Spring容器提供配置元数据:
解释Spring框架中bean的生命周期
解释不同方式的自动装配
只用注解的方式时,注解默认是使用byType的!
IoC的优点?
IoC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。
Spring框架中的单例Beans是线程安全的么?
Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态(比如Service类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。
最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”
FileSystemResource和ClassPathResource有何区别?
在FileSystemResource 中需要给出spring-config.xml文件在你项目中的相对路径或者绝对路径。在ClassPathResource中spring会在ClassPath中自动搜寻配置文件,所以要把ClassPathResource文件放在ClassPath下。
如果将spring-config.xml保存在了src文件夹下的话,只需给出配置文件的名称即可,因为src文件夹是默认。
简而言之,ClassPathResource在环境变量中读取配置文件,FileSystemResource在配置文件中读取配置文件。
https://segmentfault.com/a/1190000014979704?utm_source=sf-related
https://segmentfault.com/a/1190000017348726?utm_source=tag-newest