spring的IOC和DI
IOC是什么?
Ioc—Inversion of Control,即“控制反转”,是一种设计思想。而Spring IOC是应用了该设计思想,能过IOC容器来间接管理bean。
IOC解决什么问题?
IOC主要是起到一个解耦的作用,使程序更加灵活,主要思想是将设计好的程序对象由原来程序来主动控制交给IOC容器控制,反转就是将控制权交给容器来统一管理,而非我们从代码层面手动去控制,当需要获取该对象的时候直接到spring容器中去获取就可以了。所谓反转则是将原来需要手动new 对象(正转),交由spring IOC容器进行控制(创建、赋值、销毁等),所称反转。即
手动正转: Object xx = new Object();
IOC反转 Object xx = IOC容器创建;
个人理解:IOC就类似于父母没时间带孩子,让爷爷奶奶带(IOC),爷爷奶奶负责小孩子的吃喝玩耍,父母只负责接送,而爷爷奶奶就类似于IOC。
DI是什么?
DI的全称是:Dependency Injection(依赖注入),组件之间依赖关系由容器在运行期决定,通过DI可以为对象注入相对应的信息。就比如当将对象中的setter赋上某些值或者将对象的值赋到别外一个对象中,该行业简单DI。
个人理解:你需要挂一副画,将钉子打到墙上,这个打到墙上的行为称为DI。
IOC与DI关系
IOC是一种思想,而DI是该思想的具体实现,spring通过组件之间的依赖关系由容器在需要的时候进行注入相关的对象信息。Spring 的DI有三种实现:set注入、构造器注入、静态工厂注入、实例工厂注入
代码下载:https://gitee.com/hong99/spring/issues/I1N1DF
源码实现
/**
* @Auther: csh
* @Date: 2020/7/7 17:56
* @Description:用户信息
*/
public class User implements Serializable {
private String userName;
private int age;
public User() {
}
public User(String userName, int age) {
this.userName = userName;
this.age = age;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + ''' +
", age=" + age +
'}';
}
}
/**
* @Auther: csh
* @Date: 2020/7/7 17:56
* @Description:用户信息
*/
public class User2 implements Serializable {
private String userName;
private int age;
public User2() {
}
public User2(String userName, int age) {
this.userName = userName;
this.age = age;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + ''' +
", age=" + age +
'}';
}
}
public interface MessageService {
String getMessage();
}
@Service("messageService")public class MessageServiceImpl implements MessageService {
public String getMessage() {
return "hello world";
}
/**
* @Auther: csh
* @Date: 2020/7/7 11:44
* @Description:
*/
public class IocTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationfile*.xml");
System.out.println("context 已启动!");
//setter实现
User user = context.getBean(User.class,"user");
System.out.println("user信息:"+user.toString());
//构造方法获取
User2 user2 = context.getBean(User2.class, "user2");
System.out.println("user信息:"+user2.toString());
//自动注解方式
MessageService service = context.getBean(MessageService.class);
//打印service的信息
System.out.println(service.getMessage());
}
}
配置文件:
applicationfile-arg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!--通过构造方法注入-->
<bean id="user2" class="com.hong.spring.ioc.entity.User2" >
<constructor-arg name="age" value="111" />
<constructor-arg name="userName" value="csh2" />
</bean>
</beans>
applicationfile-scan.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!--通过构造方法注入-->
<bean id="user2" class="com.hong.spring.ioc.entity.User2" >
<constructor-arg name="age" value="111" />
<constructor-arg name="userName" value="csh2" />
</bean>
</beans>
applicationfile-setter.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!--通过属性注入-->
<bean id="user" class="com.hong.spring.ioc.entity.User" >
<property name="age" value="20" />
<property name="userName" value="csh" />
</bean>
</beans>
结果
context 已启动!
user信息:User{userName='csh', age=20}
user信息:User{userName='csh2', age=111}
hello world
代码下载:https://gitee.com/hong99/spring/issues/I1N1DF
总结
IOC的思想其实就是进行解耦,使程序更加灵活,而DI就是IOC的具体实现,主要通过注入方式直接将对IOC 的容器是spring bean通过类图发现,ApplicationContext是整个spring的入口也是核心(心脏),它是通BeanFactory的一种实现,当然ApplicationContext的实现也非常多,可以下图参照:
参考文献:
https://www.martinfowler.com/articles/injection.html
https://www.iteye.com/blog/jinnianshilongnian-1413846
https://caojiele.com/2019/03/28/spring-ioc/
https://www.javazhiyin.com/61040.html
循环依赖:
https://www.jianshu.com/p/6c359768b1dc
- hdu----(5045)Contest(数位dp)
- hdu----(5053)the Sum of Cube(签到题,水体)
- RHEL构建DNS服务器-多区域
- hdu----(5050)Divided Land(二进制求最大公约数)
- 日志分析实战之清洗日志小实例1:使用spark&Scala分析Apache日志
- RHEL构建DNS服务器-单区域
- hdu----(5047)Sawtooth(大数相乘+数学推导)
- hdu----(4522)湫湫系列故事——过年回家(最短路)
- hdu---(1421)搬寝室(dp)
- hdu----(1257)最少拦截系统(dp/LIS)
- nginx安装Fancy美化索引目录
- hdu---(3779)Railroad(记忆化搜索/dfs)
- RHEL下KVM虚拟化部署-安装虚拟化
- hdu--(1025)Constructing Roads In JGShining's Kingdom(dp/LIS+二分)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释