17.bean的作用域和生命周期

bean的作用域和生命周期

bean的作用域

在Spring中可以通过配置<bean>标签的scope属性来指定bean的作用域范围,各取值含义参加下表:

取值含义创建对象的时机
singleton(默认)在IOC容器中,这个bean的对象始终为单实例IOC容器初始化时
prototype这个bean在IOC容器中有多个实例获取bean时

如果是在WebApplicationContext环境下还会有另外两个作用域(但不常用):

取值含义
request在一个请求范围内有效
session在一个会话范围内有效

applicationContext.xml

    <!--
        scope:设置bean的作用域
            singleton(默认):bean在IOC容器中只有一个实例,IOC容器初始化时创建对象
            prototype:bean在IOC容器中可以有多个实例,getBean()时创建对象
    -->
    <bean id="StudentFour" class="com.atguigu.spring.Student" scope="prototype">
        <property name="id" value="28"></property>
    </bean>

SpringTest.java

    @Test
    public void testBean(){
        ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = ioc.getBean("StudentFour",Student.class);
        Student student1 = ioc.getBean("StudentFour",Student.class);
        System.out.println(student == student1);
    }
//运行结果:false

bean的生命周期

具体的生命周期过程

  • bean对象创建(调用无参构造器)
  • bean对象设置属性(依赖注入)
  • bean对象初始化之前操作(由bean的后置处理器postProcessBeforeInitialization()方法负责)
  • ——单例多例执行区别分割线
  • bean对象初始化(需在配置bean时指定初始化方法)
  • bean对象初始化之后操作(由bean的后置处理器postProcessAfterInitialization()方法负责)
  • bean对象就绪可以使用
  • bean对象销毁(需在配置bean时指定销毁方法)
  • IOC容器关闭

创建BeanUser.java为其无参构造、set方法添加对应的输出语句,再添加方法initMethod和destroyMethod并添加对应的输出语句

User.java

public class User {

    private Integer id;

    private String name;

    public User() {
        System.out.println("生命周期:1、创建对象");
    }

    public void setId(Integer id) {
        System.out.println("生命周期:2、依赖注入");
        this.id = id;
    }
    
    public void initMethod(){
        System.out.println("生命周期:3、初始化");
    }

    public void destroyMethod(){
        System.out.println("生命周期:5、销毁");
    }
    //省略了没有输出语句的非特殊方法

applicationContext.xml

    <!--
        使用init-method属性指定初始化方法
        使用destroy-method属性指定销毁方法
    -->
    <bean id="User" class="com.atguigu.spring.User" init-method="initMethod" destroy-method="destroyMethod">
        <property name="id" value="27"></property>
    </bean>

SpringTest.java

    @Test
    public void testBean(){
        //ConfigurableApplicationContext是ApplicationContext的子接口,它扩展了刷新和关闭容器的方法
        ConfigurableApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = ioc.getBean("User",User.class);
        System.out.println("生命周期:4、通过IOC容器获取bean并使用");
        System.out.println(user);
        ioc.close();
    }
生命周期:1、创建对象
生命周期:2、依赖注入
生命周期:3、初始化
生命周期:4、通过IOC容器获取bean并使用
User{id=27, name='null'}
生命周期:5、销毁

若bean的作用域为单例,生命周期的前三个步骤会在IOC容器创建时执行

若bean的作用域为多例,生命周期的前三个步骤会在获取bean时执行,且销毁的方法不会再由IOC容器来进行管理

bean的作用域对生命周期的影响

bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,且配置到IOC容器中,需要注意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IOC容器中所有bean都会执行

值得注意的是:bean在实现此接口后,将此bean配置到IOC容器时会导致多例的前三个步骤会和单例一样在创建IOC容器时执行,但功能并不会影响。但是调用getBean方法不会拿IOC容器中已经创建的bean,反而是重新获取新的bean,也就意味着获取bean又会执行一次前三个步骤

BeanPostProcessorTest.java实现BeanPostProcessor接口,重写其中的两个方法

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class BeanPostProcessorTest implements BeanPostProcessor{
    //IDEA通过Ctrl+O显示可重写的方法
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之前的操作");
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之后的操作");
        return null;
    }
}

因为bean后置处理器只要一个bean实现了接口,对所有bean都生效,所以需要新建一个xml文件

testApplicationContext.xml

    <!-- bean的后置处理器要放入IOC容器才能生效 -->
    <bean id="BeanPostProcessorTest" class="com.atguigu.spring.BeanPostProcessorTest"></bean>

    <bean id="User" class="com.atguigu.spring.User" init-method="initMethod" destroy-method="destroyMethod">
        <property name="id" value="27"></property>
    </bean>

SpringTest.java

    @Test
    public void testBean(){
                ConfigurableApplicationContext ioc1 = new ClassPathXmlApplicationContext("testApplicationContext.xml");
        User user = ioc1.getBean("User",User.class);
        System.out.println("生命周期:4、通过IOC容器获取bean并使用");
        System.out.println(user);
        ioc1.close();
	}
生命周期:1、创建对象
生命周期:2、依赖注入
初始化之前的操作
生命周期:3、初始化
初始化之后的操作
生命周期:4、通过IOC容器获取bean并使用
User{id=27, name='null'}
生命周期:5、销毁
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值