IOC控制反转DI依赖注入(Java EE 学习笔记06)
1 IoC 控制反转
控制反转(Inversion of Control,缩写为IoC)是面向对象编程中的一个设计原则,用来降低程序代码之间的耦合度。在传统面向对象编程中,获取对象的方式是用new关键字主动创建一个对象,也就是说应用程序掌握着对象的控制权。传统面向对象程序设计原则如图,其中商品类和商品信息类都要有业务代码直接通过new创建,然后再将对象组合使用,这样会导致类与类之间高耦合,并且难以测试。
因此,在使用Spring框架后,对象的实例化就不再由调用者来创建,而是由Spring的IoC容器来创建,IoC容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。
IoC控制反转机制指的是对象由Ioc容器统一管理,当程序需要使用对象时,可以直接从IoC容器中获取。这样对象的控制权就从应用程序转移到了IoC容器,控制权发生了反转。IoC设计原则如图,它是借助于IoC容器实现具有依赖关系对象之间的解耦,各个对象类封装之后,通过IoC容器来关联这些对象类。
2 DI 依赖注入
依赖注入(Dependency Inject,缩写DI)就是由IoC容器在运行期间动态地将某种依赖资源注入对象之中。例如,将对象B注入(赋值)给对象A的成员变量。依赖注入的基本思想是:明确地定义组件接口,独立开发各个组件,然后根据组件的依赖关系组装运行。
依赖注入(DI)和控制反转(IoC)是从不同角度来描述了同一件事情。依赖注入是从应用程序的角度描述,即应用程序依赖IoC容器创建并注入它所需要的外部资源;而控制反转是从IoC容器的角度描述,即IoC容器控制应用程序,由IoC容器反向地向应用程序注入应用程序所需要的外部资源。这里所说的外部资源可以是外部实例对象,也可以是外部文件对象等。
依赖注入的作用就是在使用Spring框架创建对象时,动态的将其所依赖的对象注入到Bean组件中。
依赖注入通常有两种实现方式,一种是构造方法注入,另一种是属性setter方法注入。
构造方法注入
构造方法注入是指Spring容器调用构造方法注入被依赖的实例,构造方法可以是有参的或者是无参的。Spring在读取配置信息后,会通过反射方式调用实例的构造方法,如果是有参构造方法,可以在构造方法中传入所需的参数值,最后创建类对象。
小小案例:
① 创建实体类User,并创建有参构造方法
package com.lq.entities;
/**
* @Author: Luqing Teacher
* @CreateTime: 2024-11-27
* @Description: 用户类,依赖注入
* @Version: 1.0
*/
public class User {
private int id;
private String name;
private String pwd;
/**
* 构造方法,通过构造进行依赖注入
* @param id
* @param name
* @param pwd
*/
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
② 创建配置文件applicationContext-user.xml,并写入实体bean并赋值
<?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.lq.entities.User">
<constructor-arg name="id" value="1"/>
<constructor-arg name="name" value="lq"/>
<constructor-arg name="pwd" value="123"/>
</bean>
</beans>
该写法也可以更改为如下:
<bean id="user" class="com.lq.entities.User">
<constructor-arg index="0" value="1"/>
<constructor-arg index="1" value="lq"/>
<constructor-arg index="2" value="123456"/>
</bean>
③ 创建测试类TestUser
package com.lq.test;
import com.lq.entities.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author: Luqing Teacher
* @CreateTime: 2024-11-27
* @Description: 测试USer
* @Version: 1.0
*/
public class TestUser {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-user.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
}
④ 输出结果如下: