两种注入形式
DI(Dependency Injection)依赖注入。
依赖注入,即组件之间的依赖关系由容器在利用零碎运行期来决定,也就是由容器动静地将某种依赖关系的指标对象实例注入到利用零碎中的各个关联的组件之中。
所谓的依赖注入其实就是,在创建对象的同时或之后,如何给对象的属性赋值。
如果对象由咱们本人创立,这所有都变得很简略,例如:
User user = new User();
user.setName("小智"); // 通过 setName 办法为 name 属性赋值
user.setAge(24); // 通过 setAge 办法为 age 属性赋值
或者:
User user = new User("小智", 24); // 在创建对象的同时, 通过有参构造函数为对象的属性赋值
若是对象由 Spring IoC 容器创立,Spring 提供两种形式为属性赋值:
1)set 办法注入
2)构造方法注入
set 办法注入
顾名思义,就是在类中提供须要注入成员的 set 办法。spring 框架底层会调用 set 办法为成员变量赋值。
例如:Spring 框架负责创立 User 的 Bean 对象之后,会通过调用 User 对象的 setName 办法为 name 属性赋值。
一般属性注入
需要:通过 Spring IoC 容器获取 User 实例,并为 User 对象的 name 和 age 属性(一般属性)赋值
1、在 User 类中申明 name 和 age 属性,并增加对应的 setter 和 getter 办法,以及重写 toString 办法
public class User {
// 提供公有成员变量
private String name;
private Integer age;
private UserInfo info;
// 提供 getter 和 setter 办法
...
// 重写 toString 办法
...
}
2、在 beans.xml 中申明 User 类的 bean 实例
<!-- 将 User 类作为 bean 拆卸到 Spring IoC 容器中(即 User 类的实例由 Spring 创立) -->
<bean id="user" class="com.tedu.pojo.User"></bean>
3、创立测试类—DITest
package com.tedu;
import org.Springframework.context.support.ClassPathXmlApplicationContext;
public class DITest {
@Test
public void testDI() {
// 获取 Spring 的 IoC 容器
ApplicationContext ctx = new
ClassPathXmlApplicationContext("beans.xml");
// 应用 getBean 办法获取对应的 POJO 并输入
User user = (User)ctx.getBean("user");
System.out.println(user);
}
}
因为这里没有为 User 对象的属性赋值,所以此时运行测试,后果为:
User[name=null,age=null,info=null]
4、批改 beans.xml 中 User Bean 标签,为 User Bean 的 name 和 age 属性注入属性值
<!-- 将 User 类作为 bean 拆卸到 Spring IoC 容器中(即 User 类的实例由 Spring 创立) -->
<bean id="user" class="com.tedu.pojo.User">
<!-- 通过 set 办法为 User Bean 的 name、age 属性赋值 -->
<property name="name" value="小智"/>
<property name="age" value="24"/>
</bean>
下面的 bean 定义表明,User bean 通过 <property> 标签为 User 对象的 name 和 age 属性赋值。
之所以称之为是 set 办法注入,是因为在框架底层会调用 User 对象的 setter 办法为属性赋值。
例如:上面 User bean 标签中的 <property> 标签是为 User 对象的属性赋值。
<property name="name" value="小智"></property>
因为 name=” name “,因而须要 User 对象中有 setName 办法才能够实现注入,否则将会注入失败。
value=” 小智 “,示意为(User 对象的)setName 办法对应的属性赋值为 ” 小智 ”。
一般属性(根本数据类型和 String 类型)间接通过 value 注入即可。
5、运行测试类 DITest,后果为:
User[name="小智",age=24,info=null]
对象属性注入
需要:通过 Spring IoC 容器获取 User 实例,并为 User 对象的 userInfo 属性 (对象属性) 赋值
1、在 beans.xml 中,将 UserInfo 类作为 bean 拆卸到 Spring IoC 容器中(如果已有能够疏忽)
<!-- 将 UserInfo 类作为 bean 拆卸到 Spring IoC 容器中(即 UserInfo 类的实例由 Spring 创立) -->
<bean id="userInfo" class="com.tedu.pojo.UserInfo"></bean>
2、在 beans.xml 中,将通过 Spring 容器获取的 UserInfo 对象作为值,注入到 User 对象的 userInfo 属性
<!-- 将 User 类作为 bean 拆卸到 Spring IoC 容器中(即 User 类的实例由 Spring 创立) -->
<bean id="user" class="com.tedu.pojo.User">
<!-- 通过 set 办法为 User Bean 的 name、age 属性赋值 -->
<property name="name" value="小智"/>
<property name="age" value="24"/>
<!-- 通过 set 办法为 User Bean 的 info(对象)属性赋值 -->
<property name="info" ref="userInfo"/>
</bean>
<!-- 将 UserInfo 类作为 bean 拆卸到 Spring IoC 容器中(即 UserInfo 类的实例由 Spring 创立) -->
<bean id="userInfo" class="com.tedu.pojo.UserInfo"></bean>
因为此处是将 UserInfo 对象的援用作为值设置给 info 属性,因而 ref 属性指定为 UserInfo 对象 bean 标签的 id 值。将通过 Spring 容器获取的 UserInfo 对象传递给 setUserInfo 办法,从而对 User 对象的属性赋值。
对象属性通过 ref 属性注入。
3、运行测试类 DITest,后果为:
User[name="小智",age=24,info=com.tedu.pojo.Userinfo@65e2dbf2]
构造方法注入
顾名思义,就是应用类中的构造函数,为成员变量赋值——即构造方法注入。
须要留神的是:为成员变量赋值是通过配置的形式,让 spring 框架在创立 bean 对象的同时,为成员变量赋值。而不是咱们本人去实现。
需要:通过 Spring IoC 容器获取 User 实例,并为 User 对象的 name、age、info 属性赋值
1、为 User 类增加无参结构和有参构造函数
// 提供无参结构
public User() {}
// 提供有参结构
public User(String name, Integer age, UserInfo info) {
this.name = name;
this.age = age;
this.info = info;
}
留神:如果不增加有参构造函数,能够无参、有参构造函数都不增加;
如果要增加有参构造函数,强烈建议同时增加无参构造函数,否则在很多中央应用时都可能会抛出异样!
2、批改 beans.xml 文件,将 set 办法批改为构造方法注入。
<!-- 将 User 类作为 bean 拆卸到 Spring IoC 容器中(即 User 类的实例由 Spring 创立) -->
<bean id="user" class="com.tedu.pojo.User">
<!-- 通过 set 办法为 User Bean 的 name、age 属性赋值
<property name="name" value="小智"/>
<property name="age" value="24"/> -->
<!-- 通过 set 办法为 User Bean 的 info(对象)属性赋值
<property name="info" ref="userInfo"/> -->
<!-- 通过构造方法为 User Bean 的 name、age、info 属性赋值 -->
<constructor-arg name="name" value="马云"/>
<constructor-arg name="age" value="30"/>
<constructor-arg name="info" ref="userInfo"/>
</bean>
<!-- 将 UserInfo 类作为 bean 拆卸到 Spring IoC 容器中(即 UserInfo 类的实例由 Spring 创立) -->
<bean id="userInfo" class="com.tedu.pojo.UserInfo"></bean>
其中,constructor-arg 标签 name 属性的值必须和构造函数中参数的名字雷同!
同样的,一般属性间接通过 value 注入即可;对象属性通过 ref 属性注入。
3、运行测试类 DITest,后果为:
User[name= 马云,age=30,info=com.tedu.pojo.UserInfo@7e3f631b]