IoC(控制反转)理论指导★★★★★
声明
本文为其他博主原创文章整合,仅用作个人学习,特此声明
参考文章链接
(3条消息) B站 - 狂神 - Spring5课堂笔记_夜里的雨的博客-CSDN博客_狂神spring5笔记
Spring:IOC本质分析探究 - 百度文库 (baidu.com)
2、IoC(控制反转)理论指导
首先,我们要搞清楚IoC到底是什么?
Spring:IOC本质分析探究 - 百度文库 (baidu.com)
2.1 传统的调用
以下内容的本质就是业务层(自己不写方法)去调用Dao层的方法
我们先用原来的方式写一段代码
1.先写一个UserDao接口
package dao;
public interface UserDao {
void getUser();
}
2.写Dao的实现类UserDaoImp
package dao;
public class UserDaoImpl implements UserDao{
public void getUser() {
System.out.println("默认获取用户数据");
}
}
3.再写一个UserService业务接口
package Service;
public interface UserService {
void getUser();
}
4.业务实现类UserServiceImp
package Service;
import dao.UserDao;
import dao.UserDaoImpl;
public class UserServiceImpl implements UserService{
UserDao userDao = new UserDaoImpl();
public void getUser(){
userDao.getUser();
}
}
5.测试
import Service.UserService;
import Service.UserServiceImpl;
public class MyTest0 {
public static void main(String[] args) {
// 用户实际调用的是业务层,dao层他们不需要接触
UserService userService = new UserServiceImpl();
userService.getUser();
}
}
以上就是我们原来写代码的方式,这种写法的弊端是显而易见的:用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改原代码!如果程序代码量十分大,修改一次的成本代价十分昂贵!
比如说我们现在要增加UserDao的实现类
package dao;
public class UserDaoMysqlImpl implements UserDao{
public void getUser() {
System.out.println("Mysql获取用户数据");
}
}
相应的,因为Dao层改了,业务层要调用Dao层的方法,我们自然要去Service实现类里修改对应实现
package Service;
import dao.UserDao;
import dao.UserDaoImpl;
public class UserServiceImpl implements UserService{
UserDao userDao = new UserDaoMysqlImpl();
public void getUser(){
userDao.getUser();
}
}
假设说我们再增加一个dao层的实现类,那么service又要进行修改
也就是说,如果我们类似的需求特别多,相应的我们就要多次修改service的实现类,这显然是很反人类的!
并且这样设计的耦合性太高了,牵一发而动全身
如何解决这种问题呢?
2.2 控制反转
以前是要程序员在dao层改,现在dao层不用改动,只用增加一个新需求的实现类,然后把这个实现类告诉客户,客户自己把名字改掉就行,保证了内部是对客户不可见的,只用提供调用的方法
我们可以在需要用到它的地方不去实现它,而是利用set
//在Service层的实现类(UserServiceImpl)增加一个Set()方法
//利用set动态实现值的注入!
public class UserServiceImpl implements UserService {
private UserDao userDao;
// 利用set实现
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
接下来测试一下
@Test
public void test(){
UserServiceImpl service = new UserServiceImpl();
service.setUserDao( new UserDaoMySqlImpl() );
service.getUser();
//那我们现在又想用Oracle去实现呢
service.setUserDao( new UserDaoOracleImpl() );
service.getUser();
}
这看起来可能没有什么变化,但是他们已经发生了根本的变化,很多地方都不一样了,以前所有东西都是由程序去进行控制创建,而现在是我们自行控制创建对象,把主动权交给了调用者, 程序不用去管怎么创建,怎么实现了 . 它只负责提供一个接口 .
反转(理解):主动权交给了用户
这种思想 , 从本质上解决了问题 , 我们程序员不再去管理对象的创建了 , 更多的去关注业务的实现 . 耦合性大大降低 . 这也就是IOC的原型 !
2.3 IoC的本质
控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
想必学到这里大伙都和我一样,还是对IoC一知半解。
没关系,现在我们通过下边的代码实例慢慢理解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)