- 属性依赖注入的三种方式
什么是Bean属性的注入?就是对一个对象的属性赋值。有三种方式:
- 第一种:构造器参数注入
- 第二种:setter方法属性注入(setter方法的规范需要符合JavaBean规范)
- 第三种:接口注入
Spring 框架规范中通过配置文件配置的方式,只支持构造器参数注入和setter方法属性注入,不支持接口注入 !
- 构造器参数注入 constructor-arg
【示例】
第一步:构造器参数注入属性值。
创建包com.igeek.xmlpropertydi,创建Car类,定义构造方法
//目标,构造器参数注入,new car直接将参数的值直接赋值
public class Car {
private Integer id;
private String name;
private Double price;
//有参构造
public Car(Integer id, String name, Double price) {
this.id = id;
this.name = name;
this.price = price;
}
//取值要用getter
public Integer getId(){
return this.id;
}
public String toString() {
return "Car [id=" + id + ", name=" + name + ", price=" + price + "]";
}
}
第二步:配置applicationContext.xml
<!-- 构造器注入属性的值 -->
<bean id="car" class="com.igeek.xmlpropertydi.Car">
<!--constructor-arg:告诉spring容器,要调用有参构造方法了,不再调用默认的构造方法了
new Car(1,"宝马",99999d)
参数第一组:定位属性
* index:根据索引定位属性,0表示第一个位置
* name:根据属性参数名称定位属性
* type:根据属性数据类型定位属性
参数第二组:值
* value:简单的值,字符串
* ref:复杂的(由spring容器创建的bean对象)
-->
<!-- <constructor-arg index="0" value="1"/> -->
<constructor-arg index="0" name="id" value="1"/>
<!-- <constructor-arg name="name" value="宝马1代"/> -->
<constructor-arg name="name" >
<value>宝马2代</value>
</constructor-arg>
<constructor-arg type="java.lang.Double" value="99999d"/>
</bean>
第三步:使用SpringTest.java测试:
@Test
public void test(){
//spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取car
Car car =(Car) applicationContext.getBean("car");
System.out.println(car);
}
【补充】
1.定位属性的标签,可以混用
<constructor-arg index="0" name="id" value="1"/>
2.自标签的属性赋值问题,可以使用子标签的value,效果和value属性一样
<constructor-arg name="name" value="宝马1代"/>
等同于
<constructor-arg name="name" >
<value>宝马2代</value>
</constructor-arg>
- setter方法属性注入 property
使用的默认的构造器(new Bean()),但必须提供属性的setter方法,使用setter方法也是企业经常使用的属性注入方式。
两步:在类中加入setter方法,在配置文件中使用<property>
【示例】
第一步:创建Person.java,定义id、name、car属性
/**
* 定义人类
* setter方法属性注入
* 相当于new Person();
*/
public class Person {
private Integer id;
private String name;
private Car car;
//必须提供setter属性方法
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", car=" + car + "]";
}
}
第二步:配置spring容器applicationContext.xml
<!-- setter方法属性注入:调用默认构造器,相当于new Person() -->
<bean id="person" class="com.igeek.xmlpropertydi.Person">
<!--
property:专门进行setter属性注入用的标签 。
* name:setter方法的属性的名字,例如SetXxx-那么name的属性值为xxx。
* value:简单的值
* ref:bean的名字,对象的引用
-->
<property name="id" value="1001"/>
<property name="name" value="Tom"/>
<!-- <property name="car" ref="car"/> --><!--等同于-->
<property name="car">
<ref bean="car"/>
</property>
</bean>
第三步:使用SpringTest.java测试:
@Test
public void test1(){
//spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取人
Person person=(Person)applicationContext.getBean("person");
System.out.println(person);
}
【扩展】
- <ref>标签的用法:
<!-- <property name="car" ref="car"/> -->
<!--等同于-->
<property name="car">
<ref bean="car"/>
</property>
2.深入理解setter方法的属性注入
抛出问题:<property name="name" value="关羽"/>里面的name,是不是必须和类中的private String name;的name一致才可以呢?能不一样么?
可以的!
修改Person.java类。
public class Person {
private Integer id;
private String pname;//其中pname和setName方法的属性不一致,而<property name="name" value="关羽"/>其中的name属性的值指的是setName()的属性名称。
private Car car;
//必须提供setter属性方法
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.pname = name;
}
public void setCar(Car car) {
this.car = car;
}
public String toString() {
return "Person [id=" + id + ", pname=" + pname + ", car=" + car + "]";
}
}