spring部分源码分析及Bean的生命周期理解

前言:

本文整体框架是通过refresh方法这个入口进入分析:分析IOC容器的创建及一些Bean的生命周期的知识点,写得确实一般般,感觉自己的有些前置知识并没有理解的很到位,所以,这篇文件先记录一下,等以后理解得好了再来更新。


整体的流程:

 

 我们先将bean的配置信息写在配置文件中,再通过ClassPathXmlApplicationContext类读取,并管理。

这个图中的入口还有一个概念:

beandefinition:Spring框架中,BeanDefinition是描述和定义Spring容器中的Bean的元数据对象。它包含了定义Bean的相关信息,例如Bean的类名、作用域、生命周期等。

接着我们打断点进入:

 

1: this.prepareRefresh()

这个方法就是定义spring容器的一些基本信息

该方法会主要做准备操作,设置初始化的数据和当任何属性资源激活后设置活动的标记。还会保存一些监听器。

2:this.obtainFreshBeanFactory()

refreshBeanFactor:创建了一个新的BeanFactory:ConfigurableListableBeanFactory

 

这里的this.loadBeanDefinitions(beanFactory)就会从配置文件中加载容器的信息。

3:this.prepareBeanFactory(beanFactory);

创建BeanFactory之后,还需要对这个BeanFactory进行一个准备工作:

例如:类加载器和后置处理器

4:this.postProcessBeanFactory(beanFactory);

我们点进去之后发现这个方法啥都没有,

这是一个空接口,允许开发人员往这个接口中加入自定义逻辑。

不同的spring容器也可以做不同的操作。

5:this.invokeBeanFactoryPostProcessors(beanFactory)

这个方法我们顾名思义调用BeanFactory的后处理器的方法,但是这个时候并不会创建Bean对象

 我们看这段源码之前,我们还涉及到了两个接口:

  • BeanFactoryPostProcessor:允许你修改现有 Bean 的定义,但不能注册新的 Bean 定义。
  • BeanDefinitionRegistryPostProcessor:允许你修改 Bean 定义和注册新的 Bean 定义,它是更高级的,通常在更早的阶段执行。

我们点进来看看。 

这段源码的逻辑比较复杂,总结下来说就是invokeBeanFactoryPostProcessors() 方法的确是用来处理 BeanFactory 的配置和注册后处理器的

 6:this.registerBeanPostProcessors(beanFactory):

这也是在注册后处理器,不过这个是专门的关于Bean生命周期的后处理器

简单理解下来就是:这个方法注册的后处理器更多,而且是与 Bean 生命周期相关的后处理器

并且这个方法也会根据不同的IOC容器进行一个注册。

7:this.initMessageSource(); this.initApplicationEventMulticaster();

国际化,applicationContext默认是支持国际化的,因为他继承了MessageSource接口所以能够实现国际化,这里不进行说明了,如有兴趣可以查询该链接


在Spring容器中初始化事件广播器,事件广播器用于事件的发布。

程序首先会检查bean工厂中是否有bean的名字和这个常量(applicationEventMulticaster)相同的,如果没有则说明没有那么就使用默认的ApplicationEventMulticaster 的实现:SimpleApplicationEventMulticaster

8: onRefresh():

点进去:

这也是一个空方法,也是留着给后面进行扩展

我们也可以感觉到,像spring这种牛逼的框架,留的扩展点也真的是不少。

9:this.registerListeners()

 注册应用的监听器。

在 Spring 框架中,registerListeners() 方法主要用于注册应用上下文(ApplicationContext)中的事件监听器。它是一个重要的机制,通过此机制,Spring 可以实现事件驱动的编程模型

这一个监听器的理解,我觉得我理解并不好,问了GPT,也不明白什么意思,这里留一个

TODO

如果以后有机会会回来补充的。 

10:this.finishBeanFactoryInitialization(beanFactory);

finishBeanFactoryInitialization 是 Spring 框架中一个关键的方法,用于完成 BeanFactory 的初始化过程它确保所有的 Bean 都已正确初始化并且容器处于可用状态

这个方法也涉及到Bean的生命周期。

Bean的生命周期:

流程图:

代码演示:

1:定义一个普通类:
public class BeanTest implements BeanNameAware, InitializingBean , DisposableBean {
    private String name;
    public BeanTest() {
        System.out.println("实例化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("依赖注入");
        this.name = name;
    }

    public void init(){
        System.out.println("初始化");
    }

    public void destory(){
        System.out.println("销毁");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean方法执行");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("BeanNameAware方法执行");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean方法执行");
    }
}
2:配置文件:
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="a" class="com.javassmprojects.bean3.BeanTest" init-method="init" destroy-method="destory">
        <property name="name" value="BeanTest"></property>
    </bean>
    <bean id="MyProcessor" class="com.javassmprojects.bean3.MyPostProcess"></bean>
</beans>
3:MyPostProcessor:
public class MyPostProcess implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if("a".equals(beanName)){
            System.out.println(beanName+"我是后处理器的before方法");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if("a".equals(beanName)) {
            System.out.println(beanName + "我是后处理器的after方法");
        }
        return bean;
    }
}
4:创建测试类测试:
class BeanTestTest {


    @Test
    public void test01(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beantest.xml");
        applicationContext.getBean("a");
        System.out.println("使用Bean对象");
        ((ClassPathXmlApplicationContext)applicationContext).close();
    }

}

测试结果:

实例化
依赖注入
BeanNameAware方法执行
a我是后处理器的before方法
InitializingBean方法执行
初始化
a我是后处理器的after方法
使用Bean对象
15:13:48.503 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext -- Closing org.springframework.context.support.ClassPathXmlApplicationContext@4fb0f2b9, started on Tue Jul 23 15:13:48 CST 2024
DisposableBean方法执行
销毁

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值