类的属性的注入:
1、通过接口方式注入:
首先,定义一个接口:
public interface Injection {
public void setName(String name);
}
然后,定义一个bean,实现这个接口:
public class InjectionImpl implements Injection{
private String name;
@Override
public void setName(String name) {
this.name=name;
}
}
2、通过构造器注入:
编写一个类,提供带参构造器:
public class User {
private String name;
public User(){
}
public User(String name){
this.name=name;
}
}
3、setter方法注入(最常用的注入方式)
例如:
public class Customer {
private String name;
public void setName(String name) {
this.name = name;
}
}
****在Spring框架中支持构造器的注入和setter方法注入,也就是DI(依赖注入)支持这两种方式。
下面举例说明Spring中bean的属性的注入:
第一种方式:构造器方式
新建bean:
package com.js.demo6;
/**
* 采用构造方式注入bean的属性
* @author js
*
*/
public class Car {
private String name;
private double price;
public Car() {
super();
}
public Car(String name, double price) {
super();
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Car [name=" + name + ", price=" + price + "]";
}
}
在applicationContext.xml中配置bean:
这里有多中配置方式:
(1)键值对注入:
(2)下标索引注入:
(3)下标索引加强注入:
一般情况下,使用构造器方式注入比较少用,更多地采用setter方法。
第二种方式:setter方法方式
新建bean:
package com.js.demo6;
/**
* 使用setter方法注入bean
* @author js
*
*/
public class Car2 {
private String name;
private double price;
public void setName(String name) {
this.name = name;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Car2 [name=" + name + ", price=" + price + "]";
}
}
在applicationContext.xml中配置bean:
刚刚注入的是普通属性,如果要注入的属性是一个对象,应该如何操作呢?
定义一个bean:
package com.js.demo6;
/**
* 这是一个人,ta有一辆车
* @author js
*
*/
public class Person {
private String name;
private Car2 car2;
public void setName(String name) {
this.name = name;
}
public void setCar2(Car2 car2) {
this.car2 = car2;
}
@Override
public String toString() {
return "Person [name=" + name + ", car2=" + car2 + "]";
}
}
配置bean:
编写测试类:
package com.js.demo6;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
public void testDemo3(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person=(Person)applicationContext.getBean("person");
System.out.println(person);
}
}
运行结果:
Person [name=小蒋, car2=Car2 [name=保时捷, price=3000000.0]]
如果一个类的属性非常的多,从Spring2.5开始,Spring提供了名称空间P来帮我们注入属性。
首先,在applicationContext.xml中引入约束:
xmlns:p="http://www.springframework.org/schema/p"
完成后如下所示:
然后我们就可以把car2的配置变成如下形式:
这样写起来就比原来简单多了。
如果属性是一个复杂对象呢?
以person为例,我们可以重新配置person如下:
这就是p名称空间的使用。
语法:#{表达式}
value="#{表达式}"
让我们用SpEL重新配置一下car2:
SpEL还能引用其他bean的属性和方法:
以person为例:
新建类PersonInfo:
package com.js.demo6;
public class PersonInfo {
private String name;
public void setName(String name) {
this.name = name;
}
}
配置PersonInfo到applicationContext.xml中:
此时,如果需要把personInfo的name注入到person中:
运行发现会出问题,为什么呢?因为PersonInfo这个bean中没有提供属性name的getter方法。
修改PersonInfo类:
package com.js.demo6;
public class PersonInfo {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
运行结果:
Person [name=小凳, car2=Car2 [name=大众, price=120000.0]]
如果我们需要在Person中调用PersonInfo中某个方法的值呢?
继续修改PersonInfo类:
package com.js.demo6;
public class PersonInfo {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String showName(){
return name;
}
}
此时,person的配置应如下所示:
【注:集合属性的注入详见下节】