Spring属性注入有四种方式,分别为set方法注入、构造函数注入、p名称空间注入、spel注入,前两种为主要的注入方式。 源码
一、set方法注入(最重要)
配置好jar包后先看看项目的框架:
实体类User.java(属性的set方法要写):
package com.rr.bean;
public class User {
private String name;
private Integer age;
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;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
配置文件applicationContext.xml(property标签中name属性对应实体类的字段名,value属性表示注入的值):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
<!-- set方式注入 -->
<bean name="user" class="com.rr.bean.User">
<property name="name" value="tom"></property>
<property name="age" value="20"></property>
</bean>
</beans>
测试代码段:
package com.rr.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.rr.bean.User;
public class JunitTest {
@Test
public void fun1() {
// 1.创建容器对象, 类路径xml
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.向容器要User对象
User user = (User)ac.getBean("user");
// 3.打印User对象
System.out.println(user);
}
}
运行结果1:
如果一个User对象还依赖一个Car对象,让“用户拥有车”,需要做如下改动:
项目结构:
bean包下新建Car类:
package com.rr.bean;
public class Car {
private String name;
private String color;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Car [name=" + name + ", color=" + color + "]";
}
}
User类添加Car属性并重新生成toString()方法:
package com.rr.bean;
public class User {
private String name;
private Integer age;
private Car car;
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 Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", car=" + car + "]";
}
}
spring配置文件applicationContext.xml, 值类型用value,引用类型用ref:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
<!-- set方式注入 -->
<bean name="user" class="com.rr.bean.User">
<!-- 值类型注入:为User对象中名为name的属性注入tom作为值 -->
<property name="name" value="tom"></property>
<property name="age" value="20"></property>
<!-- 引用类型注入:②为car属性注入下方配置的car对象 value要和①中的对象name一致-->
<property name="car" ref="car"></property>
</bean>
<!-- ①将car对象配置到容器中 -->
<bean name="car" class="com.rr.bean.Car">
<property name="name" value="Porsche"></property>
<property name="color" value="pink"></property>
</bean>
</beans>
运行刚才的测试方法,运行结果二:
二、构造函数注入:
修改之前的User类,添加两个构造方法(无参的那个方法主要是为了不影响前面的set注入):
public User() {
}
public User(String name, Car car) {
System.out.println("User constructor with 2 parameter method called!");
this.name = name;
this.car = car;
}
applicationContext.xml文件新增bean元素(constructor-arg属性用于注入构造函数):
<bean name="user2" class="com.rr.bean.User">
<constructor-arg name="name" value="Tony"></constructor-arg>
<constructor-arg name="car" ref="car"></constructor-arg>
</bean>
测试类中新添测试方法二:
@Test
public void fun2() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User)ac.getBean("user2");
System.out.println(user);
}
测试结果(在构造函数中没有初始化age字段,所以为null值):
三、p名称空间注入
①修改配置文件applicationContext.xml的约束(中间部分省略):
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p ="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
<!-- ... -->
</beans>
②以p名称空间方式新建bean:
<bean name="user3" class="com.rr.bean.User" p:name="Jack" p:age="20" p:car-ref="car" >
</bean>
③添加测试方法:
@Test
public void fun3() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User)ac.getBean("user3");
System.out.println(user);
}
运行结果:
四、SPEL(Spring Expression Language)注入:
配置文件中加入(这里取到了之前注入对象的值类型的值,不能取引用类型的值):
<bean name="user4" class="com.rr.bean.User" >
<property name="name" value="#{user.name}"></property>
<property name="age" value="#{user3.age}"></property>
<property name="car" ref="car"></property>
</bean>
测试方法:
@Test
public void fun4() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User)ac.getBean("user4");
System.out.println(user);
}
运行结果: