1.Bean的配置
可以把Spring看做一个大型的工厂,而Spring容器中的Bean就是该工厂的产品。要想使用这个工厂生产和管理Bean,就需要在配置文件中告诉它需要哪些Bean,以及需要使用何种方式将这些Bean装配在一起。
Spring容器支持两种格式的配置文件,分别是Properties文件格式和xml文件格式。在实际开发中,最常使用的xml文件格式的配置方式。
XML配置文件的根元素是<beans>,<beans>包含多个<bean>子元素,每个<bean>子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中。
一个<bean>元素中包含很多属性,具体如下:
id:是一个Bean的唯一标识符;
name:可以为Bean指定多个名称;
class;
scope:用来设定Bean实例的作用域,其属性值有singleton(单例),prototype(原型)、request、session和global Session。其默认值是singleton;
constructor-arg;
property;
ref;
value;
list;
set;
map;
entry;
注意:如果在Bean中未指定id和name,则Spring会将class值当做id使用。
2.Bean的实例化
在面向对象的程序中,要想使用某个对象,就需要先实例化这个对象。在Spring容器中,实例化Bean有三种方式,分别是构造器实例化、静态工厂方式实例化和实例工厂方式实例化。
构造器实例化
构造器实例化是指Spring容器通过Bean对应的类中默认的构造函数来实例化Bean。
Bean1.java
package cn.instance.constructor;
public class Bean1 {
}
beans1.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.xsd">
<bean id="bean1" class="cn.instance.constructor.Bean1"></bean>
</beans>
InstanceTest1.java
package cn.instance.constructor;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest1 {
@Test
public void demo01(){
//相当于从类路径(src)
String xmlPath = "cn/instance/constructor/beans1.xml";
//ApplicationContext在加载配置文件时,对bean进行实例化
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
System.out.println(applicationContext.getBean("bean1"));
}
}
demo01()方法首先定义了配置文件的路径,然后Spring容器ApplicationContext会加载配置文件。在加载时,Spring容器会通过bean1的实现类Bean1中的默认无参构造函数对Bean进行实例化,使用JUnit4测试运行demo01()方法后,控制台的输出结果为:cn.instance.constructor.Bean1@746d6d。
静态工厂方式实例化
MyBean2Factory.java
package cn.instance.static_factorry;
public class MyBean2Factory {
//使用自己的工厂创建bean实例
public static Bean2 createBean(){
return new Bean2();
}
}
beans2.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.xsd">
<bean id="bean2" class="cn.instance.static_factory.MyBean2Factory"
factory-method="createBean"> 用来告诉Spring容器,其方法名称为createBean
</bean>
</beans>
InstanceTest2.java
package cn.instance.static_factorry;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest2 {
@Test
public void demo2(){
//定义配置文件路径,相当于从类路径(src)
String xmlPath = "cninstance/static_factory/beans2.xml";
//ApplicationContext在加载配置文件时,对bean进行实例化
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
System.out.println(applicationContext.getBean("bean2"));
}
}
控制台输出的结果为:cn.itcast.instance.static_factory.Bean@2d38525
实例工厂方式实例化
实例工厂方式实例化在配置文件中,需要实例化的Bean也不是通过class属性直接指向其实例化的类,而是通过factory-bean属性配置一个实例工厂,然后使用factory-method属性确定使用工厂中的哪个方法。
Bean3.java
package cn.instance.factory;
public class Bean3 {
}
MyBean3Factory.java
package cn.instance.factory;
public class MyBean3Factory {
public MyBean3Factory(){
System.out.println("bean3工厂实例化中");
}
//创建Bean的方法
public Bean3 createBean(){
return new Bean3();
}
}
beans3.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.xsd">
<!-- 配置工厂 -->
<bean id="MyBean3Factory" class="cn.instance.factory.MyBean3Factory">
</bean>
<!-- 使用factory-bean属性配置一个实例工厂
使用factory-method属性确定使用工厂中的哪个方法
-->
<bean id="bean3" factory-bean="MyBean3Factory" factory-method="createBean"></bean>
</beans>
InstanceTest3.java
package cn.instance.factory;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InstanceTest3 {
@Test
public void demo03(){
//定义配置文件路径,相当于从类路径(src)
String xmlPath = "cn/instance/factory/beans3.xml";
//ApplicationContext在加载配置文件时,对bean进行实例化
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
System.out.println(applicationContext.getBean("bean3"));
}
}
控制台输出的结果为:cn.instance.factory.Bean3@179360
Bean的作用域
Bean有5种作用域,分别是:singleton(单例),prototype(原型)、request、session和global Session
在这5种作用域种,singleton和prototype两种是最为常用。
Singleton作用域
Hello.java
package cn.hello;
public class Hello {
}
beans4.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.xsd">
<bean id="hello" class="cn.hello.Hello" scope="prototype"></bean> scope="singleton"
</beans>
HelloTest.java
package cn.hello;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloTest {
@Test
public void demo2(){
//定义配置文件路径,相当于从类路径(src)
String xmlPath = "cn/hello/beans4.xml";
//ApplicationContext在加载配置文件时,对bean进行实例化
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
System.out.println(applicationContext.getBean("hello"));
System.out.println(applicationContext.getBean("hello"));
}
}
控制台输出:
当scope="singleton"时,输出结果cn.hello.Hello@746d6d和cn.hello.Hello@746d6d
当scope="prototype"时,输出结果cn.hello.Hello@746d6d和cn.hello.Hello@32a615
singleton作用域是Spring容器默认的作用域,当一个Bean的作用域时singleton时,Spring容器只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean的id属性值相匹配是的,就只会返回Bean的同一个实例。单例模式对于无会话状态的Bean来说是最理想的选择。
对需要保持会话状态的Bean使用prototype作用域,Spring容器会为每个该Bean的请求都创建一个新的实例。