每个程序都有很多和对象,对象之间经常有相互的调用,如果这些调用没有对应的管理的话,A类调用B类就 new 一个对象,C类调用B类又 new 一个对象,那样对系统来说,频繁地创建和销毁对象是非常浪费资源的,而且类之间的调用关系很复杂,难以维护。所以Spring 的 Bean 用依赖的方式,把创建对象所需要的参数和依赖的别的 Bean 以XML的配置方式创建好,系统需要这些Bean的时候直接从Bean的XML文件就可以获取对象的创建信息和创建的实例对象,并且可以重复地使用,每个Bean之间的关系非常清楚,维护起来也非常方便。
并且,因为所有配置Bean的信息都在XML文件中,即使项目上线,需要修改配置,或者说修改某些Bean的依赖,只需要修改XML文件就可以了。如果是普通的java项目,可能要先修改java源码,重新编译,再放到项目中,所以spring在保证项目的健壮性和扩展性的作用是很大的。
总体的来说,spring就是帮我们new好一个类,并且把这个类需要的参数信息和对象信息都配置好,我们可以直接拿到我们需要的new好的对象,而且这个对象复用性很高,项目中哪个地方需要就从spring容器中拿这个对象,所有对象的实例化都由spring管理,并且spring有很多API,他们帮我们实现了很多功能,我们需要的时候直接配置,项目中就可以使用,如Mybatis的配置,SpringMVC的配置,事务的配置等等,我们用这些东西,直接把参数配好就可以用了,下面我就放上代码演示,这些依赖注入是怎么实现的:
A类有个构造函数,构造函数的依赖注入(A类为Door.java):
package com.spring.test;
public class Door {
private String name ; //门名
/**构造函数
* @param name
*/
public Door(String name) {
super();
System.out.println("Door: 构造函数");
this.name = name;
}
public String getName() {
System.out.println("Door: getName");
return name;
}
public void setName(String name) {
System.out.println("Door: setName--" + name);
this.name = name;
}
public void openDoor() {
System.out.println("开门: 门名--" + this.name );
}
}
普通的java创建对象测试:
public static void main(String[] args) {
Door door = new Door("芝麻开门");//门类实例化对象完成
door.openDoor();//调用对象方法
}
spring创建对象:
先创建配置文件Context.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="door" class="com.spring.test.Door">
<constructor-arg type="java.lang.String" value="芝麻开门"/><!-- 配置构造函数属性值 -->
</bean>
</beans>
spring注入测试类:
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("com/spring/test/Context.xml");
Door obj = (Door) context.getBean("door");
obj.openDoor();
}
两个测试结果都一样:
Door: 构造函数
开门: 门名--芝麻开门
A类普通的属性的依赖注入(A类为Door.java):
package com.spring.test;
public class Door {
private String name ; //门名
public String getName() {
System.out.println("Door: getName");
return name;
}
public void setName(String name) {
System.out.println("Door: setName--" + name);
this.name = name;
}
public void openDoor() {
System.out.println("开门: 门名--" + this.name );
}
}
注意一定要有set方法,因为spring就是通过set方法注入参数的。
普通的java创建对象测试:
public static void main(String[] args) {
Door door = new Door();
door.setName("芝麻开门");//门类实例化对象完成
door.openDoor();//调用对象方法
}
spring创建对象:
修改配置文件Context.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="door" class="com.spring.test.Door">
<property name="name" value="芝麻开门"/> <!-- 配置属性值 -->
</bean>
</beans>
spring注入测试类:
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("com/spring/test/Context.xml");
Door obj = (Door) context.getBean("door");
obj.openDoor();
}
两个测试结果都一样:
Door: setName--芝麻开门
开门: 门名--芝麻开门
注意,用构造函数依赖注入和普通的属性注入一起用的话,先执行的是构造函数的注入。
A类对B类对象的依赖注入(A类为Door.java, B类为DoorKey.java):
修改Door.java类:
package com.spring.test;
public class Door {
private String name ; //门名
private DoorKey doorKey ; //钥匙类
public String getName() {
System.out.println("Door: getName");
return name;
}
public void setName(String name) {
System.out.println("Door: setName--" + name);
this.name = name;
}
public DoorKey getDoorKey() {
System.out.println("Door: getDoorKey");
return doorKey;
}
public void setDoorKey(DoorKey doorKey) {
System.out.println("Door: setDoorKey--" + doorKey);
this.doorKey = doorKey;
}
public void openDoor() {
System.out.println("开门: 门名--" + this.name + " , 钥匙名--" + doorKey.toString());
}
}
普通的java创建对象测试:
public static void main(String[] args) {
DoorKey doorKey = new DoorKey();
doorKey.setName("菠萝菠萝蜜");//钥匙类实例化对象完成
Door door = new Door();
door.setName("芝麻开门");
door.setDoorKey(doorKey);//门类实例化对象完成
door.openDoor();//调用对象方法
}
spring创建对象:
修改配置文件Context.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="door" class="com.spring.test.Door">
<property name="name" value="芝麻开门"/> <!-- 配置属性值 -->
<property name="doorKey">
<bean id="key" class="com.spring.test.DoorKey">
<property name="name" value="菠萝菠萝蜜"/> <!-- 配置属性值 -->
</bean>
</property>
</bean>
</beans>
spring注入测试类:
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("com/spring/test/Context.xml");
Door obj = (Door) context.getBean("door");
obj.openDoor();
}
两个测试结果都一样:
DoorKey: setName--菠萝菠萝蜜
Door: setName--芝麻开门
Door: setDoorKey--DoorKey [name=菠萝菠萝蜜]
开门: 门名--芝麻开门 , 钥匙名--DoorKey [name=菠萝菠萝蜜]
通过上面的测试我们可以知道,在Spring的XML配置文件中一个Bean其实代表的就是一个类,当不同的类之间有调用关系时,只需要把要调用的类Bean嵌入到我们的Bean中就可以了,但是如上,当A类调用B类时,B类的Bean嵌入到了A类的Bean中了,这种时候如果有个C类又要调用B类,那又要重复这样的操作,那样XML配置文件就有两个B类的Bean配置,这样配置信息就有点冗余了,所以如果B类时某个类专用的调用的Bean,可以采用上面那种方法,否则就要换下面的方法进行依赖注入。
A类对B类对象的依赖注入(A类为Door.java, B类为DoorKey.java) 修改版:
其他的都用改,只需要修改配置文件Context.xml,把B类的Bean分离出来,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="door" class="com.spring.test.Door">
<property name="name" value="芝麻开门"/> <!-- 配置属性值 -->
<property name="doorKey" ref="doorkey"></property> <!-- 配置钥匙类属性 -->
</bean>
<bean id="doorkey" class="com.spring.test.DoorKey">
<property name="name" value="菠萝菠萝蜜"/><!-- 配置属性值 -->
</bean>
</beans>
两个测试结果都一样:
DoorKey: setName--菠萝菠萝蜜
Door: setName--芝麻开门
Door: setDoorKey--DoorKey [name=菠萝菠萝蜜]
开门: 门名--芝麻开门 , 钥匙名--DoorKey [name=菠萝菠萝蜜]