在使用Spring框架开发应用的过程中,大家都知道使用Spring开发应用程序,我们应用程序中所有的Bean都是通过Spring的IOC容器来管理。将Bean注入到Spring IOC容器中的方式多种多样,如通过传统的XML方式注入,通过注解的方式注入等。本文我们就通过例子的形式看一看如何通过XML的方式向Spring IOC容器中注入一个Bean。
1、首先创建一个Maven项目,加入spring-context和Junit依赖。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2、创建一个类Computer(我们需要注入的Bean)
public class Computer {
private String name;
private String brand;
public Computer() {
System.out.println("创建Computer对象... ...");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
@Override
public String toString() {
return "Computer [name="+name+",brand="+ brand +"]";
}
}
3、在resources目录下创建beans.xml,加入Computer类的配置信息
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 在XML中配置需要注入的Bean的信息,通过property标签指定Bean的属性名称及属性值 -->
<bean id="computer" class="com.training.annotation.bean.Computer">
<property name="brand" value="Dell"></property>
<property name="name" value="Latitude"></property>
</bean>
</beans>
4、获得容器,测试Bean是否被注入
public class IOCTest {
@Test
public void testXmlIOC(){
ApplicationContext applicatoin = new ClassPathXmlApplicationContext("beans.xml");
System.out.println("容器创建完成... ...");
String[] names = applicatoin.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
Object computer = applicatoin.getBean("computer");
System.out.println(computer);
Object computer1 = applicatoin.getBean("computer");
System.out.println(computer==computer1);
}
}
执行上面的单元测试,我们会得到如下结果:
创建Computer对象... ...
容器创建完成... ...
computer
Computer [name=Latitude,brand=Dell]
true
从运行结果我们可以得知如下的一些结论:
- 在默认情况下,Spring在启动容器后会调用构造方法创建对象并放到ioc容器中。
- 默认情况下,Spring容器都是以单例模式管理Bean,所有对象在Spring容器中都只有一个实例。
5、Bean实例的初始化及销毁
使用XML的方式注入Bean时,可以通过init-method属性指定Bean的初始化方法,通过destroy-method属性指定销毁方法。
我们在Computer类中加入初始化和销毁方法:
public class Computer {
//... ...
protected void init() {
System.out.println("Init方法被调用... ...");
}
protected void destroy() {
System.out.println("Destroy方法被调用... ...");
}
}
在XML加入初始化、销毁方法的配置:
//... ...
<!-- 在XML中配置需要注入的Bean的信息,通过property标签指定Bean的属性名称及属性值 -->
<bean id="computer" class="com.training.annotation.bean.Computer" init-method="init" destroy-method="destroy">
<property name="brand" value="Dell"></property>
<property name="name" value="Latitude"></property>
</bean>
//... ...
修改单元测试代码如下:
public class IOCTest {
@Test
public void testXmlIOC(){
ClassPathXmlApplicationContext applicatoin = new ClassPathXmlApplicationContext("beans.xml");
System.out.println("容器创建完成... ...");
String[] names = applicatoin.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
Object computer = applicatoin.getBean("computer");
System.out.println(computer);
Object computer1 = applicatoin.getBean("computer");
System.out.println(computer==computer1);
applicatoin.close();
System.out.println("容器关闭了... ...");
}
}
执行单元测试,我们得到如下结果:
创建Computer对象... ...
Init方法被调用... ...
容器创建完成... ...
computer
Computer [name=Latitude,brand=Dell]
true
Destroy方法被调用... ...
容器关闭了... ...
从运行结果我们可以得知如下的一些结论:
- 在默认情况下,Spring在启动容器后会调用构造方法创建对象并放到ioc容器中。
- 对象创建完成之后,立马调用对象的初始化方法初始化对象。
- 默认情况下,ioc容器都是以单例模式管理Bean,所有对象在ioc容器中都只有一个实例。
- 对象的销毁方法在IOC容器关闭后被调用。
6、多实例配置
默认情况下,ioc容器都是以单例的模式管理Bean,如果我们要创建多个实例怎么办?在传统的配置中,我们可以通过指定scope属性来指定Bean的作用域。
在XML加入scope属性:
//... ...
<bean id="computer" class="com.training.annotation.bean.Computer" init-method="init" destroy-method="destroy" scope="prototype">
<property name="brand" value="Dell"></property>
<property name="name" value="Latitude"></property>
</bean>
//... ...
scope有如下几个值:
- prototype:多实例的,ioc容器启动并不会去调用方法创建对象放在容器中,每次获取的时候才会调用方法创建对象;
- singleton:单实例的(默认值),ioc容器启动会调用方法创建对象放到ioc容器中,以后每次获取就是直接从容器(map.get())中拿;
- request:同一次请求创建一个实例;
- session:同一个session创建一个实例;
执行单元测试,我们可以得到如下结果:
容器创建完成... ...
computer
创建Computer对象... ...
Init方法被调用... ...
Computer [name=Latitude,brand=Dell]
创建Computer对象... ...
Init方法被调用... ...
false
容器关闭了... ...
通过结果我们可以得出如下结论:
- 当将Bean的作用域(scope)设置成prototype之后,ioc容器启动并不会去调用方法创建对象放在容器中,而是每次获取的时候才会调用方法创建对象;
- 对象创建完成之后立马调用对象的初始化方法初始化对象。
- 当将Bean的作用域(scope)设置成prototype之后,每次创建的Bean都是不一样的。
- 当Bean的作用域为非单例模式(singleton)时,对象的销毁方法在IOC容器关闭时不会被调用。
7、懒加载(lazy-init)
当Bean的作用域scope为单例模式(singleton)时,通过我们上面的实例我们知道,ioc容器启动时就会立马创建对象放到ioc容器中。如果我们在单例模式下想要在第一次使用对象时才创建对象,我们可以通过指定lazy-init属性来控制。默认情况下lazy-init为false,当我们指定lazy-init为true时,ioc容器启动时不创建对象,在第一次使用(获取)Bean时创建对象,并初始化;
在XML加入lazy-init:
<bean id="computer" class="com.training.annotation.bean.Computer" init-method="init" destroy-method="destroy" lazy-init="true">
<property name="brand" value="Dell"></property>
<property name="name" value="Latitude"></property>
</bean>
执行单元测试,我们会得到如下结果:
容器创建完成... ...
computer
创建Computer对象... ...
Init方法被调用... ...
Computer [name=Latitude,brand=Dell]
true
Destroy方法被调用... ...
容器关闭了... ...
小结:
本文我们通过xml的配置方式演示了如何向Spring IOC容器中注入Bean及如何获取一个Bean实例,同时演示了如何初始化Bean、如何销毁Bean,以及如何设置Bean的作用域及scope属性的值所代表的含义,同时介绍了在单例模式下如何设置在第一次使用Bean时才创建Bean实例,希望对大家有所帮助。