Spring Framework之IoC容器
Spring IoC 概述
问题
1.什么是依赖倒置?
2.什么是控制反转?
3.什么是依赖注入?
4.它们之间的关系是怎样的?
5.优点有哪些?
依赖倒置原则 (Dependency Inversion Principle)
依赖倒置是一种设计原则。
依赖倒置包括三层含义:(1)高层模块不应该直接依赖于底层模块,两者都应依赖其抽象;(2)抽象不应依赖于细节;(3)细节应该依赖于抽象。
控制反转 (Inversion of Control)
控制反转是一种思想。其核心思想在于,合作的对象依赖关系的管理不由具体对象来完成,而是具体对象交出依赖关系的控制权,由第三方容器来集中管理。
第三方容器管理的优点:(1)依赖关系的集中管理,关系清晰且易管理;(2)降低合作对象之间的耦合程度。
举个栗子。我想在北京租一间房子,我只需要把我的需求告知链家等中介公司,通过他们整合的资源,我就能够找到一间符合我需求的房子。我不需要与房东产生任何直接的关系,中间的任何问题都由链家进行统一处理。在这个例子中,房客与房东是两个独立的对象,而链家则是充当中间容器。
依赖注入(Dependency Inversion)
依赖注入是控制反转的具体方法之一。依赖注入就是将底层依赖对象以参数形式传入上层对象。
对象间的依赖关系的管理被反转至IoC容器中。对象间的依赖关系由IoC容器进行统一管理,并由IoC容器来完成对象的注入。
依赖倒置原则 、控制反转 、依赖注入的关系
优点
1.实现模块间松耦合
2.由IoC容器来统一管理依赖关系,对象从复杂的依赖关系中解放。
3.对象自身弄够专注于自身功能上,不需要了解依赖对象的内部结构。
IoC 容器
BeanFactory
BeanFactory提供最基本的IoC容器功能和基本规范。
BeanFactory中有getBean、getType、getAliases、isSingleton、isPrototype等函数。主要常用接口是getBean,改函数能够通过Bean名称获取Bean
BeanFactory扩展接口:
(1)ListableBeanFactory:接口定义Bean的基本信息。
接口中函数有:getBeanDefinitionCount获取Bean数量、containsBeanDefinition判断容器中是否存在该Bean、getBeanDefinitionNames获取工程所有Bean的名称等。
(2)HierarchicalBeanFactory:父子容器关联
接口中函数有:getParentBeanFactory子容器可以通过函数访问到父容器
(3)ConfigurableBeanFactory:可定制IoC容器
接口中函数有:setBeanClassLoader设置Bean类加载器、setBeanExpressionResolver设置表达式解析器、registerCustomEditor注册编辑器等。
(4)AutowireCapableBeanFactory:定义Bean自动装配规则
接口中函数有:autowireBeanProperties根据名称或属性给Bean进行自动装配等。
ApplicationContext
ApplicationContext基于BeanFactory,是比BeanFactory更为高级的容器。
ApplicationContext相对于BeanFactory提供更多功能,BeanFactory中需要通过编程实现的功能,ApplicationContext中可以使用配置来实现。
ApplicationContext继承ListableBeanFactory、HierarchicalBeanFactory,除此之外还扩展了其他接口。
ApplicationContext扩展接口:
(1)ApplicationEventPublisher:封装事件发布功能。
(2)MessageSource:提供i18n国际化消息刚问功能。(解释模块中解释i18n)
(3)ResourcePatternResolver:通过路径加载资源
(4)LifeCycle:start()、stop()、isRunning(),控制与判断容器当前状态,以达到控制与调度的作用。
(5)ConfigurableApplicationContext:实现ApplicationContext,新增refresh()、close(),使ApplicationContext具备启动、刷新、关闭等功能。
IoC容器的依赖注入
基于注解定义Bean
Spring2.0开始Spring提供基于注解的依赖注入功能。使用xml进行配置使Bean定义信息与Bean实现代码分离,这就会造成代码复杂且易错。基于注解就可以在Bean实现类上进行注解标注,这大大降低的代码的复杂性。
定义Bean注解有以下4中:
(1)@Component:组件
(2)@Respository:对于Dao实现类进行标注
(3)@Service:对于Service实现类进行标注
(4)@Controller:对于Controller实现类进行标注
@Respository、@Service、@Controller是@Component的扩展,尽量使用3种特殊的注解,因为能够标识出Bean的类型。
自动装配
@Resource
resource是用J2EE提供的。
查找方式:
(1)按照指定name和type,容器中找到后对bean进行装配,找不到抛出异常。
(2)按照指定name,容器中找到后对bean进行装配,找不到抛出异常。
(3)按照指定type,容器中找到后对bean进行装配,找不到或找到多个抛出异常。
(4)没指定name和type,则先安装name方式装配,找不到这则按type进行装配,都没有抛异常。
@Autowired
autowired是spring提供的。
查找方式:
(1)按照类型查找,如果该类型bean不唯一则抛异常。
@Qualifier
查找方式:
(1)通过名称指定Bean,同一个接口有多个实现,我们要装配其中某一个Bean时,可以用qualifier通过名称直接指定,一般结合Autowired一起使用。
基于Java类配置
@Bean
普通的POJO可以通过标注@Configuration注解,就可以为Spring容器提供Bean定义信息,标注了@Bean的类方法就相当于提供了Bean的定义信息。当第三方库引入时,可以使用@Bean注解将Bean交由Spring容器进行管理。
@Configuration
public class AppConfig {
@Bean(name = "dataSource")
public DataSource initDataSource() {
return DataSourceBuilder.create().build();
}
}
相当于
<beans>
<bean id="dataSource" class="org.springframework.boot.jdbc.DataSourceBuilder"/>
</beans>
Bean的作用域
类型 | 说明 |
---|---|
singleton | IoC容器中仅存在一个Bean实例 |
prototype | 每次调用都会返回新的Bean实例 |
request | 每次Http请求都会创建一个Bean |
session | 同一个session共享Bean |
globalSession | 同一个全局Session共享一个Bean |
singleton
prototype
FactoryBean
解释说明
FactoryBean是能够生产和修饰对象生成的工厂Bean。Spring提供了org.springframework.beans.factory. FactoryBean接口,使用者能通过实现接口对Bean的实例化进行定制。
使用场景
(1)第三方框架提供的类,我们很难直接修改类代码,为其添加@Service或@Componet时。
(2)当我们需要对第三方框架生成的实例进行修饰时。
应用案例
(1) mybatis-spring中org.mybatis.spring.SqlSessionFactoryBean
IoC容器内部关系
Bean配置信息配置了Bean的实现与依赖关系,容器将Bean配置信息注册至注册表中,然后根据注册表加载与实例化,并建立Bean与Bean之间的依赖关系,最后将结果放置Bean缓存池中,供用应用程序调用。
JSR-250注释
JSR-250注释包括@PostConstruct,@PreDestroy,@Resource。@PostConstruct与@PreDestroy不用于依赖注入,用于标注对象生命周期的管理方法。
@Resource
@Resource与@Autowired的区别在上文已经讲过就不再赘述。
@PostConstruct
如果想要在对象实例化后做一些准备工作,可以使用@PostConstruct。
@Resource
private ADRFingerprintBuilder adrFingerprintBuilder;
@Resource
private IOSFingerprintBuilder iosFingerprintBuilder;
@Resource
private List<ADRChecker> adrCheckers;
@Resource
private List<IOSChecker> iosCheckers;
private static Map<String, EventTemplate> event = new HashMap<>();
@PostConstruct
public void buildEventMap() {
event.put(ClientSourceEnum.ADR.getSource(), EventTemplate.builder().builder(adrFingerprintBuilder).checkers(adrCheckers).build());
event.put(ClientSourceEnum.IOS.getSource(), EventTemplate.builder().builder(iosFingerprintBuilder).checkers(iosCheckers).build());
}
在完成实例化后,将实例放入map中,为后续操作做准备工作。
@PreDestroy
在对象销毁之前调用方法关闭资源或其他动作可以使用@PreDestroy。
@PreDestroy
public void destroy(){
System.out.println("destroy");
}
解释
- i18n:国际化信息也称为本地化信息 。 Java 通过 java.util.Locale 类来表示本地化对象,它通过 “语言类型” 和 “国家/地区” 来创建一个确定的本地化对象。比如在发送一个具体的请求的时候,在header中设置一个键值对:"Accept-Language":"zh",通过Accept-Language对应值,服务器就可以决定使用哪一个区域的语言,找到相应的资源文件,格式化处理,然后返回给客户端。
参考
[1]https://www.jianshu.com/p/6f0a59623090
[2]https://www.cnblogs.com/hujunzheng/p/11037577.html
[3]《精通Spring4.x企业应用开发实战》
[4]《Spring揭秘》
Spring Framework之IoC容器的更多相关文章
- Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->使用spring framework的IoC容器功能----->方法一:使用XML文件定义beans之间的依赖注入关系
XML-based configuration metadata(使用XML文件定义beans之间的依赖注入关系) 第一部分 编程思路概述 step1,在XML文件中定义各个bean之间的依赖关系. ...
- Spring.NET的IoC容器(The IoC container)——简介(Introduction)
简介 这个章节介绍了Spring Framework的控制反转(Inversion of Control ,IoC)的实现原理. Spring.Core 程序集是Spring.NET的 IoC 容器实 ...
- 比Spring简单的IoC容器
比Spring简单的IoC容器 Spring 虽然比起EJB轻量了许多,但是因为它需要兼容许多不同的类库,导致现在Spring还是相当的庞大的,动不动就上40MB的jar包, 而且想要理解Spring ...
- 使用Spring.NET的IoC容器
使用Spring.NET的IoC容器 0. 辅助类库 using System; using System.Collections.Generic; using System.Linq; using ...
- 框架应用:Spring framework (一) - IoC技术
IoC概念以及目标 IoC就是让原本你自己管理的对象交由容器来进行管理,其主要的目的是松耦合. IoC发展史 既然IoC的目标是为了松耦合,那它怎么做到的? 最后目标:降低对象之间的耦合度,IoC技术 ...
- Spring框架学习[IoC容器高级特性]
1.通过前面4篇文章对Spring IoC容器的源码分析,我们已经基本上了解了Spring IoC容器对Bean定义资源的定位.读入和解析过程,同时也清楚了当用户通过getBean方法向IoC容器获取 ...
- Spring基础——在 IOC 容器中 Bean 之间的关系
一.在 Spring IOC 容器中 Bean 之间存在继承和依赖关系. 需要注意的是,这个继承和依赖指的是 bean 的配置之间的关系,而不是指实际意义上类与类之间的继承与依赖,它们不是一个概念. ...
- Spring框架及IOC容器
Spring是一个非常活跃的开源框架, 它是一个基于IOC和AOP来构架多层JavaEE系统的框架,它的主要目地是简化企业开发.Spring以一种非侵入式的方式来管理你的代码, Spring提倡”最少 ...
- 【Spring】Spring之向 IOC 容器注入对象的三种方式
关于Spring的搭建可参见:浅析Spring框架的搭建.在测试之前还是应该先将环境配置好,将相关Jar包导进来.Spring创建的对象,默认情况下都是单例模式,除非通过scope指定. 向IOC容器 ...
随机推荐
- 【视频+图文】带你快速掌握Java中含break语句的双重for循环
双重for循环掌握后,我们就一起来看看双重for循环的进阶内容一之带break语句的双重for循环. 双重for循环[视频+图文]讲解传输门:点击这里可去小乔的哔哩哔哩观看~ 带continue语句的 ...
- 基于Blazor写一个简单的五子棋游戏
写这个五子棋游戏,其实主要目的是想尝试一下微软新作Blazor.Blazor对于那些搞.NET的程序员,又想做一些前端工作,真的挺友好,不用一句JS就可搞定前端交互,美哉.现在已经有很流行的前端框架, ...
- 一位资深程序员大牛推荐的Java技术学习路线图
Web应用,最常见的研发语言是Java和PHP. 后端服务,最常见的研发语言是Java和C/C++. 大数据,最常见的研发语言是Java和Python. 可以说,Java是现阶段中国互联网公司中,覆盖 ...
- 从头认识js-HTML中使用JavaScript
<script>元素 在HTML页面中插入Javascript的主要办法就是使用<script>元素,HTML4.01为<script>定义了下列6个属性. 1.a ...
- C语言入门理解指针
本文章为本人原创,适合于刚入坑C语言,对于指针的定义和用法模糊不清的同学,如有不正,请各位指出. 从根本来说,指针变量也是变量,只是int变成了int *,以此类推.只不过指针变量里面放的内容是普通变 ...
- C#编程_单线程IP地址解析
单线程IP地址解析 目标程序 界面如下图 设计方法:完成单个IP地址解析,循环调用方法,完成扫描. 注意用stopwatch计算时间. 实现思路 先知道怎么解析一个单个的IP地址. 用循环的方法解 ...
- 2020年,大厂常问iOS面试题汇总!
Runloop & KVO runloop app如何接收到触摸事件的 为什么只有主线程的runloop是开启的 为什么只在主线程刷新UI PerformSelector和runloop的关系 ...
- Java——JDBC
今天给大家更新一篇我自己学习Java——JDBC的经验 Java中JDBC是(Java DataBase Connectivity)的简称,由java语言编写的类和接口组成,可为多种关系型数据库提供了 ...
- 05 mapreduce快速入门
统计HDFS的/wordcount/input/a.txt文件中的每个单词出现的次数——wordcount package cn.oracle.core; import java.io.IOExcep ...
- socket TCP 从0实现音频传输 ALSA 播放
RTP标准是采用 UDP 发送,有不少现成的开源库,但不在本文讨论的范围内.UDP 用户数据报,不提供流程,安全传输的功能,但速度快,能提供多播,广播,没有序列号 SEQ ,有 MTU 限制,1500 ...