目录
引言
Spring框架中的依赖注入(Dependency Injection,DI)是一种设计模式和编程实践,它通过反转控制(Inversion of Control, IoC)实现组件之间的解耦。在传统的对象创建过程中,一个类通常需要自己创建并管理对其他类的引用,这会导致高度耦合。而依赖注入则是由一个第三方容器(IOC容器)负责创建对象,并将这些对象所依赖的对象实例作为构造函数参数、setter方法或字段直接注入到目标对象中。
在Spring框架中,依赖注入可以通过构造函数注入、Setter方法注入或字段注入来实现。通过依赖注入,开发人员可以将对象之间的依赖关系配置在Spring容器中,然后由Spring容器在运行时动态地将依赖关系注入到对象中,从而实现对象之间的解耦和灵活的管理。这样可以使得代码更加模块化和易于扩展,同时也方便进行单元测试和集成测试。
1、依赖注入之setter注入
①创建学生类Student
public class Student {
private Integer id;
private String name;
private Integer age;
private String sex;
public Student() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" + "id=" + id + ", name='" + name + ", age=" + age + ", sex='" + sex }';
}
}
②配置bean时为属性赋值
property标签就是通过组件类的setXxx()方法给对象设置属性,在运行时容器会动态地将依赖关系注入到对象。
<bean id="studentOne" class="com.softeem.bean.Student">
<!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 -->
<!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关)
-->
<!-- value属性:指定属性值 -->
<property name="id" value="1001"></property>
<property name="name" value="张三"></property>
<property name="age" value="23"></property>
<property name="sex" value="男"></property>
</bean>
③测试
getBean()方法里面的参数一定要配置文件中bean标签中的id一致
@Test
public void studentTest(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = ac.getBean("studentOne", Student.class);
System.out.println("student = " + student);
}
2、依赖注入之构造器注入
①在Student类中添加有参构造
public Student(Integer id, String name, Integer age, String sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
②配置bean
<bean id="studentTwo" class="com.softeem.bean.Student">
<constructor-arg value="1002"></constructor-arg>
<constructor-arg value="李四"></constructor-arg>
<constructor-arg value="33"></constructor-arg>
<constructor-arg value="女"></constructor-arg>
</bean>
注意:
constructor-arg标签还有两个属性可以进一步描述构造器参数:
index属性:指定参数所在位置的索引(从0开始)
name属性:指定参数名
③测试
@Test
public void testDIBySet(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-di.xml");
Student studentOne = ac.getBean("studentTwo", Student.class);
System.out.println(studentOne);
}
3、为类类型属性赋值(依赖注入之对象注入)
①创建班级类Clazz
public class Clazz {
private Integer clazzId;
private String clazzName;
public Integer getClazzId() {
return clazzId;
}
public void setClazzId(Integer clazzId) {
this.clazzId = clazzId;
}
public String getClazzName() {
return clazzName;
}
public void setClazzName(String clazzName) {
this.clazzName = clazzName;
}
@Override
public String toString() {
return "Clazz{" +
"clazzId=" + clazzId +
", clazzName='" + clazzName + '}';
}
public Clazz() {
}
public Clazz(Integer clazzId, String clazzName) {
this.clazzId = clazzId;
this.clazzName = clazzName;
}
}
②修改Student类
在Student类中添加班级类属性及get、set方法。
为类类型属性赋值方式一:引用外部已声明的bean
配置Clazz类型的bean:
<bean id="clazzOne" class="com.softeem.bean.Clazz">
<property name="clazzId" value="1111"></property>
<property name="clazzName" value="财源滚滚班"></property>
</bean>
为Student中的clazz属性赋值:
<bean id="studentFour" class="com.softeem.spring.bean.Student">
<property name="id" value="1004"></property>
<property name="name" value="赵六"></property>
<property name="age" value="26"></property>
<property name="sex" value="女"></property>
<!-- ref属性:引用IOC容器中某个bean的id,将所对应的bean为属性赋值 -->
<property name="clazz" ref="clazzOne"></property>
</bean>
<property name="clazz" ref="clazzOne"></property> 就是property为clazz属性赋值,但此处不能用value进行赋值而要使用ref,对Clazz类型的bean参考。可以看到ref属性的值就是Clazz类型bean的id。
为类类型属性赋值方式二:内部bean
<bean id="studentFour" class="com.softeem.bean.Student">
<property name="id" value="1004"></property>
<property name="name" value="赵六"></property>
<property name="age" value="26"></property>
<property name="sex" value="女"></property>
<property name="clazz">
<!-- 在一个bean中再声明一个bean就是内部bean -->
<!-- 内部bean只能用于给属性赋值,不能在外部通过IOC容器获取,因此可以省略id属性 -->
<bean class="com.softeem.bean.Clazz">
<property name="clazzId" value="2222"></property>
<property name="clazzName" value="远大前程班"></property>
</bean>
</property>
</bean>
为类类型属性赋值方式三:级联属性赋值(用的极少)
<bean id="studentFour" class="com.softeem.spring.bean.Student">
<property name="id" value="1004"></property>
<property name="name" value="赵六"></property>
<property name="age" value="26"></property>
<property name="sex" value="女"></property>
<!-- 一定先引用某个bean为属性赋值,才可以使用级联方式更新属性 -->
<property name="clazz" ref="clazzOne"></property>
<property name="clazz.clazzId" value="3333"></property>
<property name="clazz.clazzName" value="最强王者班"></property>
</bean>
4、为数组类型属性赋值
这个简单,只用在property标签中增加array标签即可,然后在value属性赋值:
<property name="hobbies">
<array>
<value>抽烟</value>
<value>喝酒</value>
<value>烫头</value>
</array>
</property>
综上就是Spring框架中IOC容器依赖注入的几种方法。
spring框架概述及第一个入门实验见作者spring框架专栏中https://blog.youkuaiyun.com/m0_66111719/article/details/135839708?spm=1001.2014.3001.5501