Spring之DI(依赖注入)
1、DI(依赖注入)解释
- Spring官网上的解释为:依赖注入(DI)是一个过程,通过该过程,对象仅通过构造函数参数,工厂方法的参数或在构造或创建对象实例后在对象实例上设置的属性来定义其依赖关系(即,与它们一起工作的其他对象)。从工厂方法返回。然后,容器在创建bean时注入那些依赖项。此过程从根本上讲是通过使用类的直接构造或服务定位器模式来控制bean自身依赖关系的实例化或位置的bean本身的逆过程(因此称为Control Inversion)。
- 是不是看着官网的解释我感觉云里雾里的,但是听了“狂神”的关于DI的解释后我感觉焕然大悟,建议大家去看看“狂神”的视频讲的是真的很好,其实归结起来很简单。
依赖:就是实体类的容器的创建依赖于容器。
注入:就是实体类的属性由容器进行注入。 - DI(依赖注入)的注入方式有:基于有参构造函数的注入、基于set方法的注入以及其它拓展注入。
2、基于有参构造函数的注入
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--基于有参构造函数的依赖注入-->
<bean id="person" class="com.my.pojo.Person">
<!--通过参数名称进行注入-->
<!--<constructor-arg name="name" value="张三"/>
<constructor-arg name="age" value="18"/>
<constructor-arg name="job" ref="job"/>-->
<!--通过参数类型进行注入-->
<!--<constructor-arg type="java.lang.String" value="张三"/>
<constructor-arg type="int" value="18"/>
<constructor-arg type="com.my.pojo.Job" ref="job"/>-->
<!--通过参数索引进行注入-->
<constructor-arg index="0" value="张三"/>
<constructor-arg index="1" value="18"/>
<constructor-arg index="2" ref="job" />
</bean>
<bean id="job" class="com.my.pojo.Job">
<constructor-arg name="jobName" value="保安"/>
<constructor-arg name="jobAddress" value="天安门"/>
<constructor-arg name="salary" value="10000"/>
</bean>
</beans>
- constructor-arg标签:它的作用是表示使用有参构造函数进行依赖注入。
- name属性:通过有参构造函数中参数的名称进行查找要注入的实体类属性。
- type属性:通过匹配有参构造函数的参数的类型进行注入。
- index属性:通过有参构造函数中参数的索引进行注入,index索引从0开始。
- value属性:非对象属性注入的值。
- ref属性:要注入对象的标签,该对象必须在容器中进行注册后才能进行注入。
- 总结:基于有参构造函数进行注入可以通过参数的名称和类型以及索引精确定位到每一个参数,然后通过value和ref进行注入实体类属性的值或者对象。
3、基于set方法注入
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--基于set方法的依赖注入-->
<bean id="person" class="com.my.pojo.Person">
<property name="name" value="张三"/>
<property name="age" value="18"/>
<property name="job" ref="job"/>
</bean>
<bean id="job" class="com.my.pojo.Job">
<property name="jobName" value="保安"/>
<property name="jobAddress" value="天安门"/>
<property name="salary" value="10000"/>
</bean>
</beans>
- 这个配置是基于基本属性和对象进行的,set注入还有一些复杂属性注入,我们还可以通过set注入进行一些复杂的属性进行注入例如:list、set、map、Properties 、null
- property标签:表示对实体类属性进行set注入。
- 复杂属性注入:
<bean id="student" class="com.my.pojo.Student">
<!--普通属性注入-->
<property name="name" value="张三"/>
<!--list属性注入-->
<property name="course">
<list>
<value>语文</value>
<value>数学</value>
<value>外语</value>
</list>
</property>
<!--set属性注入-->
<property name="hobby">
<set>
<value>唱</value>
<value>跳</value>
<value>rap</value>
</set>
</property>
<!--map属性注入-->
<property name="teacher">
<map>
<entry key="语文" value="李老师"/>
<entry key="数学" value="王老师"/>
<entry key="外语" value="赵老师"/>
</map>
</property>
<!--Properties属性注入-->
<property name="attribute">
<props>
<prop key="age">18</prop>
<prop key="sex">男</prop>
</props>
</property>
<!--null属性注入-->
<property name="girlfriend">
<null/>
</property>
</bean>
- 这些复杂类型的属性注入其实没什么好讲的,只要大家记住每种类型注入的格式就行了。
3、其他拓展注入
- 关于其他拓展注入有很多,像什么p命名空间注入、c命名空间注入等。我在这里就只给大家介绍一下P命名空间注入。
- 首先需要引入P命名空间的依赖
xmlns:p="http://www.springframework.org/schema/p"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--基于set方法的依赖注入-->
<!-- <bean id="person" class="com.my.pojo.Person">
<property name="name" value="张三"/>
<property name="age" value="18"/>
<property name="job" ref="job"/>
</bean>-->
<!--P命名空间注入-->
<bean id="person"
class="com.my.pojo.Person"
p:name="张三"
p:age="18"
p:job-ref="job"/>
<bean id="job" class="com.my.pojo.Job">
<property name="jobName" value="保安"/>
<property name="jobAddress" value="天安门"/>
<property name="salary" value="10000"/>
</bean>