Spring中的Bean

Bean的配置

Spring可以被看作是一个大型工厂,这个工厂的作用就是生产和管理Spring容器中的Bean。

如果想要在项目中使用这个工厂,就需要开发者对Spring的配置文件进行配置。

Spring容器支持XMLProperties两种格式的配置文件,在实际开发中,最常使用的就是XML格式的配置文件。这种配置方式通过XML文件来注册并管理Bean之间的依赖关系。

在Spring中,XML配置文件的根元素是<beans>,<beans>中包含了多个<bean>子元素,每一个<bean>子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中。

<bean>元素中同样包含了多个属性以及子元素,如下等:

属性或子元素名称描述
id

是一个Bean的唯一标识符,Spring容器对Bean的配置、管理都通过该属性来完成

name同样通过此属性对Bean进行配置和管理,name属性中可以为Bean指定多个名称,每个名称之间用逗号或分号隔开
class该属性指定了Bean的具体实现类,它必须是一个完整的类名、实用类的全限定名
ref可以用于指定Bean工厂中某个Bean实例的引用

上面的表格中只是列表了部分常用的,通常一个普通的Bean只需要定义 id(或name)和 class两个属性即可。例如:

    <bean id="accountDao" class="com.dfbz.dao.imp.AccountDaoImpl"></bean>

注意:如果在Bean中未指定 id 和 name ,则Spring会将class值当作id使用

Bean的实例化

在面向对象的程序中,想要使用某个对象,就需要先实例化这个对象。同样,在Spring中,要想使用容器中的Bean,也需要实例化Bean。

实例化Bean有三种方式:构造器实例化静态工厂方式实例化实例工厂方式实例化

构造器实例化(常用)

构造器实例化是指Spring容器通过Bean对应类中默认的无参构造方法来实例化Bean。

    <bean id="studentService" class="com.dfbz.service.Impl.StudentServiceImpl"></bean>

 在Spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时,采用的就是默认构造函数创建bean对象。

静态工厂方式实例化

该方式要求开发者创建一个【静态工厂的方法来创建Bean的实例】其Bean配置中的class属性所指定的不再是Bean实例的实现类,而是静态工厂类,同时还需要使用 factory-method属性来指定所创建的静态工厂方法。

public class StaticFactory {

    public static AccountService getAccountService(){

        return new AccountServiceImpl();
    }
}

配置文件:

    <bean id="accountService" class="cn.itcast.factory.StaticFactory" 
          factory-method="getAccountService">
    </bean>

class:静态工厂类的全路径类名

factory-method:静态工厂类中的方法名

通过factory-method属性来告诉Spring容器,方法名称是:getAccountService

实例工厂方式实例化

在这种方式的工厂类中,不再使用静态方法创建Bean实例,而是采用直接创建Bean实例的方式。

同时在配置文件中,需要实例化的Bean也不是通过class属性直接指向的实例化类,而是通过factory-bean属性指向配置的实例工厂,然后使用factory-method属性确定使用工厂中的哪个方法。

public class InstanceFactory {

    public AccountService getAccountService(){

        return new AccountServiceImpl();
    }
}
<bean id="instanceFactory" class="cn.itcast.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" 
      factory-method="getAccountService"></bean>
    

在配置文件中,首先配置一个工厂Bean,然后配置了需要实例化的Bean。

在id为accountService的Bean中,使用 factory-bean属性指定配置的实例工厂,该属性就是工厂Bean的id,使用 factory-method属性来确定使用工厂中的 getAccountService方法。

Bean的作用域

通过Spring容器创建一个Bean的实例时,不仅可以完成Bean的实例化,还可以为Bean指定特定的作用域。

Bean标签的scope属性:用于指定bean的作用范围

作用域的种类

singleton(默认)、 prototype 是最常用的两种

作用域名称说明 
singleton(单例)使用singleton定义的Bean在Spring容器中将只有一个实例,也就说,无论有多少个Bean引用它,始终将指向同一个对象
prototype(多例)每次通过Spring容器获取的prototype定义的Bean时,容器都将创建一个新的Bean实例

singleton(共享)

singleton是Spring容器默认的作用域,当Bean的作用域为singleton时,Spring容器就只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean的id属性相同,就会返回同一个Bean实例。singleton作用域对于无会话状态的Bean来说,是最理想的选择。

在Spring配置文件中,Bean的作用域是通过<bean>元素的scope属性来指定的,该属性值可以设置为 singleton、prototype、request、session、globalSession、application 和 websocket 七个值。

<bean id="studentService" class="com.dfbz.service.Impl.StudentServiceImpl" scope="singleton">
</bean>

注意:如果不设置 scope = “singleton”,其输出结果也是同一个实例,因为Spring容器默认的作用域就是 singleton。

prototype(创建新的)

对需要保持会话状态的Bean应该使用prototype作用域。在使用 prototype作用域时,Spring容器会为每个对该Bean的请求都创建一个新的实例

<bean id="studentService" class="com.dfbz.service.Impl.StudentServiceImpl" scope="prototype">
</bean>

Bean的生命周期

Spring根据Bean的作用域来选择管理方式。

对于 singleton 作用域的Bean,Spring能够精确地知道该Bean何时被创建,何时初始化完成,以及何时被销毁;

对于 prototype 作用域的Bean,Spring只负责创建,当容器创建了Bean的实例后,Bean的实例就交给客户端代码管理,Spring容器将不再跟踪其生命周期。

单例对象:

  • 出生:当容器创建时对象出生
  • 活着:只要容器还在,对象一直活着
  • 死亡:容器销毁,对象死亡
  • 总结:单例对象的生命周期和容器相同

多例对象:

  • 出生:当使用对象时Spring框架
  • 活着:对象只要是在使用过程中就一直活着
  • 死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收

Bean 的定义 -> Bean 的初始化 -> Bean 的使用 -> Bean 的销毁

在Spring中,Bean生命周期的执行是一个很复杂的过程,可以利用Spring提供的方法来定制Bean的创建过程。当一个Bean被加载到Spring容器时,它就具有了生命。而Spring容器在保证一个Bean能够使用之前,会做很多工作。

Spring容器中的Bean的生命周期流程如下图:

Bean的生命周期的整个执行过程描述如下:

  1. Spring启动,查找并加载需要被Spring管理的Bean,进行Bean的实例化(调用Bean构造方法或工厂方法实例化)
  2. 利用依赖注入完成Bean中所有属性值的配置注入
  3. 如果Bean实现了BeanNameAware接口的话,则Spring调用Bean的 setBeanName()方法传入当前的Bean的id值
  4. 如果Bean实现了BeanFactoryAware接口的话,则Spring调用 setBeanFactory()方法传入当前工厂实例的引用
  5. 如果Bean实现了ApplicationContextAware接口的话,则Spring调用Bean的 setApplicationContext()方法传入当前ApplicationContext实例的引用
  6. 如果 BeanPostProcessor 和 Bean 关联,则Spring将调用该接口的预初始化方法postProcessBeforeInitialization()对 Bean 进行加工操作,这个非常重要,Spring的AOP就是用它实现的。
  7. 如果Bean实现了InitializingBean接口,则Spring将调用afterPropertiesSet()方法。类似的,如果在配置文件中通过 Bean使用init-method属性指定了初始化方法,则调用该初始化方法
  8. 如果 BeanPostProcessor 和 Bean 关联,则Spring将调用该接口的初始化方法postProcessAfterInitialization()方法。此时,Bean已经可以被应用系统使用了
  9. 此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文,直到应用上下文被销毁。如果该Bean的作用范围是【singleton】,则将Bean放入SpringIOC的缓冲池中,将触发Spring对该Bean的生命周期管理;如果该Bean的的作用范围是【prototype】,则将该Bean交给调用者,调用者管理该Bean的生命周期,Spring不再管理该Bean。
  10. 如果Bean实现了DisposableBean接口,则Spring会调用destory()方法将Spring中的Bean销毁;同样,如果在配置文件中Bean通过destory-method属性指定Bean的销毁方法,则Spring将调用该方法进行销毁

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值