深度理解SpringIOC,面试你根本不需要慌!
文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star!
搜索关注微信公众号 码出Offer 领取各种学习资料!

深度理解Spring IOC(控制反转)
一、IOC概述
Inverse Of Controll即为控制反转,简称IOC 。
简单来说,IOC反转了依赖关系的满足方式,由之前的自己创建依赖对象,变为由工厂推送。(变主动为被动,即反转)它解决了具有依赖关系的组件之间的强耦合,使得项目形态更加稳健
二、什么是IOC?
2.1 了解IOC思想
大概了解了IOC是控制反转,至于现在我们并不清楚它的思想和作用。那么问题来了,IOC(控制反转)是什么呢?
控制反转,简称IOC。顾名思义,它是由“控制”和“反转”两个词语组合而成。那么我们就顺藤摸瓜,分别分析一下这两个词语!
2.2 控制
控制一词,我们需要想的就很多。比如说,达成控制的条件必须是两个对象 ,控制可以分为谁控制谁 ,控制你做什么 。那我们一一列举这几种情况:
- 在Java中我们以new的方式创建对象,开发者控制控制着开发工具并间接的控制程序创建所需要的依赖对象,对于程序来说是直接的控制创建对象;如果使用IOC呢?那就可以是IOC容器直接的控制创建对象
- 既然是IOC控制创建对象,那么控制创建对象是怎么控制的呢?使用IOC创建对象是需要标签引入外部对象,这说明了IOC容器控制着创建依赖对象的入口
2.3 反转
反转一词,我们想的也很多。比如说,达成反转的条件必须是两个对象 ,有反转就有正转 ,然后就是反转了些什么 。那么我们也一一列举说明:
- 在Java中我们是间接的实用程序来创建对象,这可以看作正转。那有了IOC容器,一下子就变了,我们不用自己new对象,而是直接反转为由IOC创建生成依赖对象并存入IOC容器中
- 使用IOC容器创建对象我们只需要通过配置来告诉它需要创建的对象是什么,并标识一下以后使用什么来获取IOC容器中创建好的对象即可(配置使用IOC的过程),这时候等你想要IOC容器中对象就直接用这个唯一标识来获取就好,而获取的过程肯定是IOC通过这个唯一标识来查找并返回给我们该对象
- 也许有的小伙伴还是不明白反转。为什么要把IOC容器帮我们创建对象的行为叫反转呢?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象。如果不反转呢?开发者就需要创建对象,并找到、获取、使用该对象,此过程中的所有都有开发者来控制的
三、IOC的作用
通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
比如:Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。
在使用了IOC之后呢?A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(xml)来指定
既然由配置文件来指定创建对象关系,就大大降低了各个组件之间的强耦合并有利于维护,是项目变得更加稳健灵活
四、IOC解决Dao层和Service层的强耦合
在原始的Web开发中,Dao层和Service层是密不可分的。Dao层为数据访问层,只与数据库打交道。Servcie层为业务处理层,只处理实现相应的业务。而我们将Web开发中的Dao层和Service层串在一起,就需要在Service层new一个私有的Dao层实现对象(XxxDaoImpl)。有了IOC的思想,再想想传统的Dao层与Service层的实现就显得很不灵活,一旦修改了Dao层实现类,就必须将项目中的源码都修改掉,显然是一件非常可怕的事情。
五、使用IOC解决Dao层和Service层的强耦合
既然解决Dao层和Service层的强耦合那必须得这两个组件对吧。
Dao层
// Dao层接口
package com.mylifes1110.dao;
import com.mylifes1110.bean.User;
public interface UserDao {
int insertUser(User user);
}
// Dao层实现类
package com.mylifes1110.dao.impl;
import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public int insertUser(User user) {
System.out.println("------insertUser and UserDao------");
return 0;
}
}
注意: 我们在使用IOC时,必须将Dao层实现类对象注入到IOC容器中,这必有一个注入方式来告知IOC容器创建对象和获取对象,在Service层我们并不需要new实现类对象,而是创建一个Service层的Setter方法来注入UserDaoImpl依赖到UserServcieImpl中(这里可以把它们想为拼装),此时所用的注入方式叫做Setter方法依赖注入,现在不需要纠结,后续我会将依赖注入的所有方式列举并分析依赖注入思想和依赖注入与IOC的关系。
Service层
// Service层接口
package com.mylifes1110.service;
import com.mylifes1110.bean.User;
public interface UserService {
int insertUser(User user);
}
// Service层实现类
package com.mylifes1110.service.impl;
import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;
import com.mylifes1110.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public int insertUser(User user) {
System.out.println("------insertUser and UserService------");
return userDao.insertUser(null);
}
}
spring-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/beans/spring-context.xsd">
<!--id:唯一标识 class:需要被创建的目标对象全限定名-->
<bean id="UserDao" class="com.mylifes1110.dao.impl.UserDaoImpl"/>
<!--id:唯一标识 class:需要被创建的目标对象全限定名-->
<bean id="UserService" class="com.mylifes1110.service.impl.UserServiceImpl">
<!--Setter方法依赖注入 name:Service层定义的userDao属性 ref:Dao层bean标签唯一标识-->
<property name="userDao" ref="UserDao"/>
</bean>
</beans>
测试类
/**
* @MethodName insertUser1
* @Param []
* @Description 测试IOC的使用
* @Author Ziph
* @Date 2020/7/12
*/
@Test
public void insertUser1() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
UserService userService = (UserService) context.getBean("UserService");
userService.insertUser(null);
// 打印结果
------insertUser and UserService------
------insertUser and UserDao------
}

深度理解SpringIOC,面试你根本不需要慌!的更多相关文章
- 深度理解Jquery 中 offset() 方法
参考原文:深度理解Jquery 中 offset() 方法
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- Java深度理解——Java字节代码的操纵
导读:Java作为业界应用最为广泛的语言之一,深得众多软件厂商和开发者的推崇,更是被包括Oracle在内的众多JCP成员积极地推动发展.但是对于 Java语言的深度理解和运用,毕竟是很少会有人涉及的话 ...
- 深度理解IIS下部署ASP.NET Core2.1 Web应用拓扑图
原文:深度理解IIS下部署ASP.NET Core2.1 Web应用拓扑图 IIS部署ASP.NET Core2.1 应用拓扑图 我们看到相比Asp.Net, 出现了3个新的组件:ASP.NET Co ...
- 大数据学习day15----第三阶段----scala03--------1.函数(“_”的使用, 函数和方法的区别)2. 数组和集合常用的方法(迭代器,并行集合) 3. 深度理解函数 4 练习(用java实现类似Scala函数式编程的功能(不能使用Lambda表达式))
1. 函数 函数就是一个非常灵活的运算逻辑,可以灵活的将函数传入方法中,前提是方法中接收的是类型一致的函数类型 函数式编程的好处:想要做什么就调用相应的方法(fliter.map.groupBy.so ...
- unity销毁层级物体及 NGUI 深度理解总结
http://www.2cto.com/kf/201311/258811.html 1.想找到层级面板中某个物体,并销毁,利用下面的代码: GameObject obj = GameObjec ...
- 深入理解SpringIOC容器
转载来源:[https://www.cnblogs.com/fingerboy/p/5425813.html] 前言: 在逛博客园的时候突然发现一篇关于事务的好文章,说起spring事物就离不开AOP ...
- 深度理解python中的元类
本文转自:(英文版)https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python (翻译版) http:// ...
- spring5 源码深度解析----- 被面试官给虐懵了,竟然是因为我不懂@Configuration配置类及@Bean的原理
@Configuration注解提供了全新的bean创建方式.最初spring通过xml配置文件初始化bean并完成依赖注入工作.从spring3.0开始,在spring framework模块中提供 ...
随机推荐
- 如何解决在electron里无法使用puppeteer的evaluate函数
报错如图,只需要注释掉 index.html 含有 http-equiv="Content-Security-Policy 的 meta 标签就可以了.
- vim改变字体和查看映射的(mapping)命令
临时修改.通过gvim Command MODE,输入如下命令即可: Linux/Unix: set guifont=Monospace\空格14 注意这里需要对空格使用\进行转义 Windows: ...
- ZooKeeper使用入门
ZooKeeper简介 ZooKeeper是一个分布式的,开源的分布式应用程序协调服务,是Hadoop的子项目之一.它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护.域名服务.分布式 ...
- 良心之作送你几个Xsheel使用小技巧
❝ 工作中无可避免的会使用到Xsheel,接下来咔咔给你介绍几个小技巧,让你工作游刃有余. ❞ 一.告别繁琐 你的Xsheel连接后是不是这样的 哦!这个也太烦了我至少得在敲俩次命令才能到我的工作目录 ...
- Python学习日志-03
(3)如何运行程序 交互提示模式下编写代码: 最简单的运行Python程序的办法就是在Python交互命令行中输入这些程序.在cmd中输入python,不需要任何参数就可以进入Python交互命令行 ...
- 【Java】错误: 需要class, interface或enum
今天在用cmd实现mvn package操作时跳出来的报错! 网上搜索到的结论是因为编码问题而产生的,具体原因就不深究了 要详细了解可以查看以下链接https://blog.csdn.net/qq_3 ...
- docker配置国内镜像地址,解决无法pull镜像问题docker: Error response from daemon
问题: 执行命令 $ docker run -it --rm -p 8888:8080 tomcat:8.5.32 报错 Unable to find image 'tomcat:8.5.32' lo ...
- Python数据可视化实战:实时更新海外疫情数据,实现数据可视化
前言 我国的疫情已经得到了科学的控制,开始了全面的复工复产,但是国外的疫情却“停不下来”.国外现在可谓就是处于水深火热当中啊,病毒极强的传染性,导致了许多的人都“中招”了,我国已经全面复工复产了,人大 ...
- 05.DBUnit的使用
相信做过单元测试的人都会对JUnit 非常的熟悉了,今天要介绍的DbUnit(http://dbunit.sourceforge.net/ ) 则是专门针对数据库测试的对JUnit 的一个扩展,它可以 ...
- spring boot 和shiro的代码实战demo
spring boot和shiro的代码实战 首先说明一下,这里不是基础教程,需要有一定的shiro知识,随便百度一下,都能找到很多的博客叫你基础,所以这里我只给出代码. 官方文档:http://sh ...