Spring中Bean的配置、实例化、作用域、生命周期和装配方式

您所在的位置:网站首页 spring中bean的两种注入方式 Spring中Bean的配置、实例化、作用域、生命周期和装配方式

Spring中Bean的配置、实例化、作用域、生命周期和装配方式

2024-06-17 18:40| 来源: 网络整理| 查看: 265

目录 1 Bean的配置1.1 概述1.2 属性或子元素 2 Bean的实例化2.1 构造器实例化2.2 静态工厂方式实例化2.3 实例工厂方式实例化 3 Bean的作用域3.1 singleton作用域3.2 prototype作用域 4 Bean的生命周期4.1 Spring中Bean的生命周期的意义4.2 Spring容器管理Bean部分作用域的生命周期4.2.1 singleton作用域4.2.2 prototype作用域 4.3 Spring容器中Bean的生命周期流程 5 Bean的装配方式5.1 什么是Bean的装配5.2 装配方式5.2.1 基于XML的装配方式5.2.1.1 设值注入5.2.1.2 构造注入 5.2.2 基于注解(Annotation)的装配方式5.2.2.1 使用方法 5.2.3 自动装配方式 参考文章

1 Bean的配置 1.1 概述

  举个生动的例子吧。如果把Spring看作是一个大工厂的话,那么Bean就是这个工厂里的产品。当我们要使用这些产品的时候,就需要工厂为我们生产,工厂还需要管理这些产品,这就需要我们告诉工厂我们需要哪些产品(Bean),以及需要使用何种方式将这些产品(Bean)装配到一起。   Bean的本质其实就是Java中的类,而Spring中的Bean其实就是对实体类的引用,来生产Java类对象,从而实现生产和管理Bean。   在Spring容器中,支持两种格式的配置文件:Properties文件和XML文件。在实际的开发中,最常使用的是XML文件格式的配置方式,这种配置方式是通过XML文件来注册并管理Bean之间的依赖关系。

1.2 属性或子元素 XML配置文件的根元素是包含了多个子元素,每一个子元素定义一个Bean元素常用属性如下: 属性或子元素名称描述id是一个Bean的唯一标识符,Spring容器对Bean的配置、管理都通过该属性来完成nameSpring容器同样可以通过此属性对容器中的Bean进行配置和管理,name的属性中可以为bean指定多个名称,每个名称之间用逗号或分号隔开class该属性指定了Bean的具体实现类,必须是一个完整的类名,使用类的全限定名scope用来设定Bean实例的作用域,属性值有:singleton(单例)、prototype(原型)、request、session、global session、application和websocket,默认值为singleton……

  配置文件中,一个普通的Bean只需要定义id(或name)和class两个属性即可,如下:

  注:要是没有指定Bean的id和name,则Spring会将class的值当作id使用。

2 Bean的实例化

  实例化:在面向对象的程序中,要想使用某个对象,就需要先实例化这个对象。在Spring中实例化Bean有三种方式:

构造器实例化静态工厂方式实例化实例工厂方式实例化

  注:比较常用的是构造器实例化

2.1 构造器实例化

  构造器实例化是指Spring容器通过Bean对应的类中默认的构造函数来实例化Bean。使用构造器来创建Bean实例是最常见的情况,如果不采用构造注入,Spring底层会调用Bean类的无参数构造器来创建实例,因此要求该Bean类提供无参数的构造器。采用默认的构造器创建Bean实例,Spring对Bean实例的所有属性执行默认初始化,即所有的基本类型的值初始化为0或false;所有的引用类型的值初始化为null。   使用如下:

2.2 静态工厂方式实例化

  静态工厂是实例化Bean的另一种方式。该方式要求自己创建一个 静态工厂的方法来创建Bean的实例。使用静态工厂方法创建Bean实例时,class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类,Spring通过该属性知道由哪个工厂类来创建Bean实例。   除此之外,还需要使用factory-method属性来指定静态工厂方法,Spring将调用静态工厂方法返回一个Bean实例,一旦获得了指定Bean实例,Spring后面的处理步骤与采用普通方法创建Bean实例完全一样。   使用如下:

2.3 实例工厂方式实例化

  实例工厂是采用直接创建Bean实例的方式,在配置文件中,通过factory-bean属性配置一个实例工厂,然后使用factory-method属性确定使用工厂中哪个方法。实例工厂方法与静态工厂方法只有一个不同:调用静态工厂方法只需使用工厂类即可,而调用实例工厂方法则需要工厂实例。使用实例工厂方法时,配置Bean实例的元素无须class属性,配置实例工厂方法使用factory-bean指定工厂实例。 采用实例工厂方法创建Bean的元素时需要指定如下两个属性:

factory-bean: 该属性的值为工厂Bean的id。factory-method: 该属性指定实例工厂的工厂方法。

  使用如下:

3 Bean的作用域

  Spring 4.3中定义了7种作用域,如下所示:

这里边singleton和prototype是最常用的两种作用域。

3.1 singleton作用域

  singleton是Spring容器默认的作用域,容器里就只会存在一个共享的实例,无论我们调用多少次,就只存在一个。singleton作用域对于无会话状态的Bean(如Dao组件、Service层组件)来说,是最理想的选择。 无会话状态的Bean就是说只要给一个输入和输出,就会做相应的业务逻辑,不记录之前所做的任何事情。

配置方式: 在Spring的配置文件中使用元素的scope属性,将Bean的作用域定义为singleton。 3.2 prototype作用域

  对需要保持会话状态的Bean(如Struts 2的Action类)应该使用prototype作用域。在使用prototype作用域的时候,Spring容器会为每个对该Bean的请求都创建一个新的实例。也就是说我们每一次获取的都是不一样的实例。在Web的交互层我们一般需要prototype。

配置方式: 在Spring的配置文件中使用元素的scope属性,将Bean的作用域定义为prototype。 4 Bean的生命周期 4.1 Spring中Bean的生命周期的意义

  了解Spring中的Bean的生命周期的意义就在于,可以利用Bean在其存活期间的特定时刻完成一些相关操作。这种时刻可能有很多,但一般情况下,常会在Bean的postinitiation(初始化后)和predestruction(销毁前)执行一些相关操作。

4.2 Spring容器管理Bean部分作用域的生命周期 4.2.1 singleton作用域

  Spring容器可以管理singleton作用域的Bean的生命周期。在此作用域下,Spring能够精确知道该Bean何时被创建,何时被初始化,以及何时被销毁。

4.2.2 prototype作用域

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

4.3 Spring容器中Bean的生命周期流程

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

ApplicationContext容器中,Bean的生命周期流程如上图所示,流程大致如下:

首先容器启动后,会对scope为singleton且非懒加载的bean进行实例化;按照Bean定义信息配置信息,注入所有的属性;如果Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就获得了自己在配置文件中的id;如果Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFactory;如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Bean的ApplicationContext,这样该Bean就获得了自己所在的ApplicationContext;如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法;如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法;如果Bean配置了init-method方法,则会执行init-method配置的方法;如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法;经过流程9之后,就可以正式使用该Bean了,对于scope为singleton的Bean,Spring的ioc容器中会缓存一份该bean的实例,而对于scope为prototype的Bean,每次被调用都会new一个新的对象,其生命周期就交给调用方管理了,不再是Spring容器进行管理了;容器关闭后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法;如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean的生命周期结束。

参考链接:https://www.jianshu.com/p/3944792a5fff

5 Bean的装配方式 5.1 什么是Bean的装配

  Bean的装配其实可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,有:

基于XML的装配基于注解(Annotation)的装配(最常用)自动装配 5.2 装配方式 5.2.1 基于XML的装配方式

推荐使用设值注入,好用且容易理解。

5.2.1.1 设值注入

  与传统的JavaBean的写法更相似,程序开发人员更容易理解、接受。通过setter方法设定依赖关系显得更加直观、自然。对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化其依赖的全部实例,因而导致性能下降。而使用设值注入,则能避免这些问题。尤其在某些成员变量可选的情况下,多参数的构造器更加笨重。

5.2.1.2 构造注入

  构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。对于依赖关系无需变化的Bean,构造注入更有用处。因为没有setter方法,所有的依赖关系全部在构造器内设定,无须担心后续的代码对依赖关系产生破坏。依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系,对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。

5.2.2 基于注解(Annotation)的装配方式 5.2.2.1 使用方法 创建接口UserDao,并定义方法: public interface IUserDao { public void save(); } 创建接口实现类UserDaoImpl,用@Repository声明类: package cn.edu.ujn.annotation; import org.springframework.stereotype.Repository; @Repository("userDao") public class UserDaoImpl implements IUserDao { @Override public void save() { System.out.println("UserDaoImpl saving........"); } } 创建接口UserService,并定义方法: public interface IUserService { public void save(); } 创建接口实现类UserServiceImpl,用@Service声明类,并使用@Resource注入UserDao属性: package cn.edu.ujn.annotation; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("userService") public class UserServiceImpl implements IUserService { public UserServiceImpl() { System.out.println("UserServiceImpl构造方法被调用"); } @Resource(name="userDao") private IUserDao userDao; @Override public void save() { // TODO Auto-generated method stub this.userDao.save(); System.out.println("UserServiceImpl saving......"); } } 创建控制器类,用@Controller声明,并使用@Resource注入UserService属性: @Controller("userController") public class UserController{ @Resource(name="userService") private UserService userService; public void save(){ this.userService.save(); } } 创建Spring配置文件,配置Bean:

除了通过元素来配置Bean外,还可以通过包扫描的形式来配置一个包下的所有Bean:

创建测试文件,测试类 5.2.3 自动装配方式

  所谓自动装配,就是将一个Bean自动的注入到到其他Bean的Property中。Spring的元素中包含一个autowire属性,我们可以通过设置autowire的属性值来自动装配Bean。autowire属性有5个值,其值及说明下表所示:

参考文章

https://www.runoob.com/w3cnote/basic-knowledge-summary-of-spring.html

声明: 若本人发布的作品涉及版权或存在其他问题,请联系我进行删除。 谢谢浏览!


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3