在Spring中,对象无需自己查找或创建与其所关联的其他对象(解耦合)。
Spring容器负责创建应用程序中的bean并通过DI来协调Java对象之间的关系。
创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入(DI)的本质。
总而言之,bean对象就是应用程序中的Java对象,Spring容器创建并封装这些Java对象为容器中的bean对象,在需要时自动注入到变量中,赋予对应Java对象的实例。
bean
Spring配置bean的三种方式
- 1.在XML中进行显式配置。
- 2.在Java中进行显式配置。
- 3.隐式的bean发现机制和自动装配。
本文以XML中的显式配置介绍bean对象的创建方式、作用范围、生命周期等。
创建bean的方式
1 通过构造函数创建Java对象对应的bean
1.1 无参构造函数(默认构造函数)
<bean id="accountService" class="com.simple.service.impl.AccountServiceImpl" ></bean>
如上,通过AccountServiceImpl
的默认构造函数创建了AccountServiceImpl
实例化的bean对象。在Java代码中定义的 AccountServiceImpl 类或其父类对象变量,会根据变量名对应bean的id自动注入。
1.1 带参构造函数
<bean id="accountDao" class="com.simple.Dao.impl.AccountDaoImpl" ></bean>
<bean id="accountService" class="com.simple.service.impl.AccountServiceImpl" >
<constructor-arg ref="accountDao"></constructor-arg>
<constructor-arg value="#{T(其他各种类型,如string等等)}"></constructor-arg>
</bean>
accountDao
代表在AccountServiceImpl
类构造函数中需要注入的Java对象,ref 属性的值为该Java对象对应的bean的id值;#{T}
是Spring中的EL表达式,T表示构造函数中带有的其他类型参数(基本类型,如String等等)。
2 使用普通工厂中的方法创建对象,并存入指定的bean
使用某个工厂类中的方法创建Java对象,并存入spring容器。
工厂类:
public class InitFactory {
public IAccountService getAccountService(){
return new AccountServiceImpl();
}
}
XML配置:
<bean id="initFactory" class="com.simple.factory.InitFactory"></bean>
<bean id="accountService" factory-bean="initFactory" factory-method="getAccountService"></bean>
3 使用工厂中的静态方法创建对象,并存入指定的bean
使用某个类中的静态方法创建Java对象,并存入spring容器。由于使用的是工厂中的静态方法,所以不需要实例化工厂。
工厂类:
public class staticFactory {
public static IAccountService getAccountService(){
return new AccountServiceImpl();
}
}
XML配置:
<bean id="accountService" class="com.simple.factory.staticFactory" factory-method="getAccountService"></bean>
上述三种创建bean的方式中,一般使用第1种方法通过构造函数创建bean。
bean的作用范围
bean的作用范围由 bean 标签的 scope 属性来指定。其属性值包括:
属性值 | 说明 |
---|---|
singleton | 默认值,指定bean为单例的 |
prototype | 指定bean为多例的 |
request | web项目中,作用于request域 |
session | web项目中,作用于session域 |
global-session | web项目中,作用于集群环境的session域;若不是集群环境,则相当于session |
一般常用的是 singleton
,即单例的。
单例的bean表示Spring容器中该bean只有一个对应的实例化Java对象;多例的bean表示Spring容器中该bean可以有对应类多个实例化Java对象(可通过其存储地址区分)。
bean对象的生命周期
1 单例bean
- 默认情况下,Spring读取XML配置文件创建Spring容器时bean对象就会被创建
- 在创建对象时,先执行对象的构造方法,然后调用bean标签的
init-method="..."
属性值中指定的方法 - 在Spring容器销毁时,单例bean随之消亡。bean消亡即对象被销毁时,会调用bean标签的
destroy-method="..."
属性值中指定的方法 - 可以设置bean标签的
lazy-init="true"
使该对象在第一次被访问时才创建
XML配置:创建单例bean,指定init-method="..."
和destroy-method="..."
属性
<bean id="accountService" class="com.simple.service.impl.AccountServiceImpl"
scope="singleton" init-method="init" destroy-method="destory">
</bean>
AccountServiceImpl 类:
public class AccountServiceImpl implements IAccountService {
//默认无参构造器
public AccountServiceImpl() {
System.out.println("对象已创建!");
}
public void saveAccount() {
System.out.println("Service中的saveAccount方法执行了!!");
}
//初始时执行方法
public void init(){
System.out.println("对象初始化了!!!");
}
//销毁时执行方法
public void destory(){
System.out.println("对象销毁了!!!");
}
}
测试单例bean的生命周期:
public class Client {
public static void main(String[] args) {
//1.获取Spring核心容器对象
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //bean.xml放在根目录下,所有可以直接写文件名
//2.根据id获取bean对象
//可以使用强制类型转换
//IAccountService as = (IAccountService) ac.getBean("accountService");
//也可以指定对象类型
IAccountService as = ac.getBean("accountService",IAccountService.class);
//查看创建的as对象
System.out.println(as);
//执行as对象的方法
as.saveAccount();
//手动销毁Spring容器,查看as对象消亡过程
ac.close();
System.out.println("结束!");
}
}
结果如下:
2 多例bean
- Spring读取XML配置文件创建Spring容器时,不会立刻创建多例bean对应的对象
- 在每一次访问这个多例bean对应的对象的时,spring容器都会创建该对象,并且调用
init-method=".."
属性值中所指定的方法 - Spring容器销毁时,多例bean对应创建的对象也不会消亡。因为是多例的(该类型的对象可以有多个),所以在Spring容器创建该对象并将它赋予给Java变量后,该对象就由Java的进行管理,销毁该对象也由垃圾回收机制进行回收。spring容器一旦把这个对象交给Java之后,就不再管理这个对象了