Spring IOC和DI
控制反转IOC
例子:
你想吃面包,这时候有两种情况:
1 你家附近没有面包店,你就要自己买原材料自己做面包(传统编程模式:需要自己new对象)
2 你家附近有面包店,那么你只要把你想要吃的口味告诉店家,一会你就可以吃到面包了(控制反转:自己不new对象,对象由框架交给你)
注意:你没有制作面包,而是由店家制作面包,但是完全符合你的口味
控制反转:就是对象由Spring容器创建和管理,调用者只负责使用,降低耦合度,控制权由调用者转移到Spring容器,控制权产生了反转。
依赖注入:从Spring容器角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,相当于为调用者注入它所依赖的实例。
所以,控制反转是一种通过描述(Spring中可以是XML文件或注解)并通过第三方去产生或获取特定对象的方式。
Spring中实现控制反转的是IOC容器,其实现方式是依赖注入(DI)
IOC容器的设计主要是基于BeanFactory和ApplicationContext两个接口
applicationContext.xml
<bean id="test" class="dao.TestDaoImpl" />
dao/ITestDao.java(接口)
package dao; public interface ITestDao { public void sayHello(); }
dao/TestDaoImpl.java(实现类)
package dao; public class TestDaoImpl implements ITestDao{ public void sayHello() { // TODO Auto-generated method stub System.out.println("Hello,Study hard!"); } }
test/Tests.java(测试类)
package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import dao.ITestDao; public class Tests { @Test public void test1() { //初始化spring容器ApplicationContext,加载配置文件 ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml"); //通过容器获取test实例 ITestDao tt = (ITestDao) appCon.getBean("test"); tt.sayHello(); } }
依赖注入(DI):
依赖注入是Spring中实现IOC容器的方法,其作用是在使用spring框架创建对象时动态的将其所依赖的对象或属性值注入bean组件中
依赖注入通常使用两种方式实现:构造方法注入和setter方法注入
1.构造方法注入
applicationContext.xml内容
<!-- 将指定类DIServiceImpl配置给spring,让spring创建其实例 -->
<bean id="myTestDao" class="dao.TestDaoImpl"></bean>
<!-- 使用构造方法注入 -->
<bean id="diService" class="service.DIServiceImpl">
<!-- 将myTestDao注入到DIServiceImpl类的属性ITestDao上 -->
<constructor-arg index="0" ref="myTestDao" />
</bean>
service.IDIService.java
package service;
/**
* 使用构造方法依赖注入ITestDao接口对象
*
* Title: IDIService
*
* Description:
*
* @author Ethan
*
* @date 2019年6月25日
*
*/
public interface IDIService {
public void sayHello();
}
service.DIServiceImpl.java
package service;
/**
* IDIService接口的实现类
*
* Title: DIServiceImpl
*
* Description:
*
* @author Ethan
*
* @date 2019年6月25日
*
*/
import dao.ITestDao;
public class DIServiceImpl implements IDIService{
private ITestDao iTestDao;
//构造方法,用于实现依赖注入接口对象iTestDao
public DIServiceImpl(ITestDao iTestDao) {
super();
this.iTestDao = iTestDao;
}
public void sayHello() {
//调用iTestDao中的sayHello方法
iTestDao.sayHello();
System.out.println("IDIService构造方法注入");
}
}
测试类:
test.Tests2.java
package test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.IDIService;
public class Tests2 {
/**
* 构造方法注入测试类
*
* Title: Test1
*
* Description:
*
*
*/
@Test
public void Test1() {
ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
IDIService ts = (IDIService) appCon.getBean("diService");
ts.sayHello();
}
}
运行结果:
Hello,Study hard!
IDIService构造方法注入
2 setter方法注入
在上面的结构中加入service.DIServiceImpl.java
package service;
import dao.ITestDao;
public class DIServiceImpl1 implements IDIService{
private ITestDao iTestDao;
//添加iTestDao的setter方法,用于实现依赖注入
public ITestDao getiTestDao() {
return iTestDao;
}
public void setiTestDao(ITestDao iTestDao) {
this.iTestDao = iTestDao;
}
public void sayHello() {
// TODO Auto-generated method stub
//调用iTestDao中的sayHello方法
iTestDao.sayHello();
System.out.println("TestDaoImpl setter方法注入");
}
}
applicationContext.xml加入
<!-- 使用setter方法的注入 -->
<bean id="testDIService1" class="service.DIServiceImpl1">
<!-- 调用DIServiceImpl1类的setter方法,将myTestDao注入到DIServiceImpl1类的属性iTestDao上 -->
<property name="iTestDao" ref="myTestDao" />
</bean>
测试类:Tests2.java中加入
/**
* 使用setter方式注入测试类
*
* Title: Test2
*
* Description:
*
*
*/
@Test
public void Test2() {
ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
IDIService ts = (IDIService) appCon.getBean("testDIService1");
ts.sayHello();
}
运行结果:
Hello,Study hard!
TestDaoImpl setter方法注入
思考:
1 IOC容器的实现方式有哪些?
2 在spring框架中什么是控制反转?什么是依赖注入?使用控制反转与依赖注入有什么优点?
3 spring框架采用java的什么机制进行依赖注入
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」