Spring源码学习(十一)---Bean的作用域和生命周期进行测试

这里主要是使用org.springframework:spring-beans:5.2.0.RELEASE进行分析


1. 查看源码相关的快捷键

快捷键作用
Ctrl + Shift+i出现类似于预览的小窗口
Ctrl + Enter(接上步)完全打开源码
Ctrl + 鼠标左键一步到位打开源码 = Ctrl + Shift+i –>Ctrl + Enter
Alt+7查看类的有什么方法
ctrl+f12查看继承方法
ctrl+h查看接口的实现类
alt+7查看类的有什么方法
2下shift全局搜索整个项目

一. Bean的生命周期

1. Bean的生命周期流程图

在这里插入图片描述

2. Bean的生命周期流程分析

  1. 启动IOC容器
  2. 实例化bean
  3. 如果Bean实现了BeanNameAware接口,则调用setBeanName(String name)返回beanName,该方法不是设置beanName,而只是让Bean获取自己在BeanFactory配置中的名字
  4. 如果Bean实现BeanFactoryAware接口,会回调该接口的setBeanFactory(BeanFactory beanFactory)方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFactory
  5. 如果Bean实现了ApplicationContextAware接口,则调用该接口的setApplicationContext(ApplicationContext applicationContext)方法,设置applicationContext
  6. 如果有Bean实现了BeanPostProcessor接口,则调用该接口的postProcessBeforeInitialzation(Object bean,String beanName)方法,将此BeanPostProcessor应用于给定的新bean实例
  7. 如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法
  8. 如果Bean配置了init-method方法,则会执行init-method配置的方法
  9. 如果Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization(Object bean,String beanName)方法
  10. 到此为止,spring中的bean已经可以使用了,这里又涉及到了bean的作用域问题,对于singleton类型的bean,Spring会将其缓存;对于prototype类型的bean,不缓存,每次都创建新的bean的实例
  11. 如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法销毁bean
  12. 如果用户配置了定destroy-method,则调用自定义方法销毁bean

3. LifeCycleBean注册

LifeCycleBean注册

在这里插入图片描述

package com.xizi.liftcycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class LifeCycleBean implements
		BeanNameAware,
		BeanFactoryAware,
		ApplicationContextAware,
		InitializingBean,
		DisposableBean {

	// 姓名
	private String name;
	// 年龄
	private int age;

	@Override
	public void setBeanName(String name) {
		System.out.println("01-->BeanNameAware接口被调用了, 获取到的beanName:" + name);
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("02-->BeanFactoryAware接口被调用了");
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		System.out.println("03-->ApplicationContextAware接口被调用了");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("05-->InitializingBean接口被调用了");
	}

	public void myInit() {
		System.out.println("06-->myInit方法被调用了");
	}

	@Override
	public void destroy() throws Exception {
		System.out.println("09-->DisposableBean接口被调用了");
	}

	public void myDestroy() {
		System.out.println("10-->自定义destroy-method方法被调动了");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "MyLifeCycleBean{" + "name='" + name + '\'' + ", age=" + age + '}';
	}
}

4. 实现BeanPostProcessor 后置处理器接口

LifeCycleBeanPostProcessor

在这里插入图片描述

package com.xizi.liftcycle;

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

public class LifeCycleBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof LifeCycleBean) {
			System.out.println("04-->调用postProcessBeforeInitialization方法, 获取到的beanName: " + beanName);
			((LifeCycleBean) bean).setName("戏子666");
		}
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof LifeCycleBean) {
			System.out.println("07-->调用postProcessAfterInitialization, 获取到的beanName: " + beanName);
			((LifeCycleBean) bean).setAge(20);
		}
		return bean;
	}

}
<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myLifeCycleBean" class="com.xizi.liftcycle.LifeCycleBean"
          destroy-method="myDestroy"
          init-method="myInit">
        <property name="name" value="戏子777"/>
        <property name="age" value="21"/>
    </bean>
    <bean id="myBeanPostProcessor" class="com.xizi.liftcycle.LifeCycleBeanPostProcessor"/>

</beans>


5. 进行生命周期测试

进行生命周期测试

在这里插入图片描述

    @Test
    public void test13() {
        // 生命周期测试
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans2.xml");
        LifeCycleBean myLifeCycleBean = applicationContext.getBean("myLifeCycleBean", LifeCycleBean.class);
        System.out.println("08-->bean可以被使用了, beanInfo: " + myLifeCycleBean.toString());
        ((ClassPathXmlApplicationContext) applicationContext).destroy();
    }

二. Bean作用域

1、单例Singleton:在整个应用中,只创建bean的一个实例,在IOC容器中共享,容器创建的时候就实例化了这个bean

2、原型Prototype:每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例,相当于每次都new bean(),容器创建的

时候没有实例化了bean,而是请求获取的时候才会创建对象

3、会话Session:只是在Web应用中,为每个http session创建一个bean实例

4、请求Rquest:只是在Web应用中,为每个http请求创建一个bean实例,这个bean实例只在当前request请求内有效,请求结束的时候,这个

bean实例被销毁

5、全局会话GlobalSession:只是在Web应用中使用,仅在使用portlet context的时候有效

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值