首先我们先创建两个类:
汽车类Car
package source;
public class Car {
private String name;
public Car() {}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Car(String name) {
System.out.println("begin to Car");
this.name = name;
}
@Override
public String toString() {
return "Car: name=" + name;
}
}
Person类
package source;
public class Person {
private Car car;
private String num;
public Person() {}
public void setCar(Car car) {
this.car = car;
}
public void setNum(String num) {
this.num = num;
}
public Person(Car car,String num) {
System.out.println("begin to Person");
this.car = car;
this.num = num;
}
@Override
public String toString() {
return "Person: car=" + car + " num =" + num;
}
}
依赖注入的方式
构造器注册
通过构造方法注入Bean的属性和值
<bean id="car" class="source.Car">
<constructor-arg value="宝马"></constructor-arg>
</bean>
<bean id="person" class="source.Person">
<constructor-arg ref="car"></constructor-arg>
<constructor-arg value="666"></constructor-arg>
</bean>
测试类
public class Test {
public static void main(String[] args) {
String path = "applicationContext.xml";
// 1.创建Spring 的IOC的容器对象
ApplicationContext ctx = new ClassPathXmlApplicationContext(path);
Car car = (Car)ctx.getBean("car");
System.out.println(car);
Person person = (Person) ctx.getBean("person");
System.out.println(person);
}
}
结果:
begin to Car
begin to Person
Car: name=宝马
Person: car=Car: name=宝马 num =666
属性注入
通过set方法注入Bean的属性和值
注意;一定要提供无参构造函数,否则会出错!!!
<bean id="car" class="source.Car">
<property name="name" value="奥迪"></property>
</bean>
<bean id="person" class="source.Person">
<property name="car" ref="car"></property>
<property name="num" value="777"></property>
</bean>
测试结果:
Car: name=奥迪
Person: car=Car: name=奥迪 num =777
集合属性
如果在Bean中存在集合属性, Spring中可以通过一组内置的XML标签(<list>、<set>、<map>)来配置集合属性
我们先建立一个Factory类
package source;
import java.util.List;
public class Factory {
private List<Car> carList;
public Factory(){}
public Factory(List<Car> carList) {
this.carList = carList;
}
public List<Car> getCarList() {
return carList;
}
public void setCarList(List<Car> carList) {
this.carList = carList;
}
@Override
public String toString() {
String num = "";
for(Car car:carList) {
num += "carName=" + car.getName() + " ";
}
return num;
}
}
配置文件修改如下
<bean id="car1" class="source.Car">
<property name="name" value="宝马"></property>
</bean>
<bean id="car2" class="source.Car">
<property name="name" value="林肯"></property>
</bean>
<bean id="factory" class="source.Factory">
<property name="carList" >
<list>
<ref bean="car1"></ref>
<ref bean="car2"></ref>
</list>
</property>
</bean>
测试结果:
carName=宝马 carName=林肯
使用p命名空间
使用p命名空间,可以简化我们的配置
举个例子,原来我们需要这样写
<bean id="car" class="source.Car">
<property name="name" value="奥迪"></property>
</bean>
<bean id="person" class="source.Person">
<property name="car" ref="car"></property>
<property name="num" value="777"></property>
</bean>
如果我们使用p命名空间,就只需要这样写,是不是简单了很多?
<bean id="car" class="source.Car" p:name="劳斯莱斯"></bean>
<bean id="person" class="source.Person" p:car-ref="car" p:num="888"></bean>
Bean的作用域
Bean的作用域由scope属性指定。scope属性有两个很重要的值,一个是singleton,他是默认值,使用单例模式。而另一个是prototype,使用多例模式。
SPEL表达式
<bean id="car" class="source.Car">
<property name="name" value="本田"></property>
</bean>
<bean id="person" class="source.Person" >
<!-- 使用SPEL引用其他Bean -->
<property name="car" value="#{car}"></property>
<!-- 使用SPEL引用其他Bean的属性 -->
<property name="num" value="#{car.name}"></property>
</bean>
测试结果:
Car: name=本田
Person: car=Car: name=本田 num =本田