Spring-IoC之BeanFactory源码分析(Annotation)

本文深入剖析Spring框架中Bean的加载流程,从ApplicationContext的初始化到Bean的实例化,详细解读了ConfigurationClassPostProcessor、BeanFactoryPostProcessor等关键组件的作用及其实现原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext();
        context.register(AppConfig.class);
        context.refresh();
        UserDao dao = (UserDao) context.getBean("userDao");
        UserDao dao1 = (UserDao) context.getBean("userDao");
        System.out.println("dao:"+dao.hashCode()+"->dao1:"+dao1.hashCode());
        dao.query();
    }

执行context的构造new AnnotationConfigApplicationContext();
在这里插入图片描述
执行子类的构造之前会先执行父类的构造,所以先看下AnnotationConfigApplicationContext父类的构造方法做了什么事情
在这里插入图片描述
可以看到,在父类的构造方法当中完成了BeanFactory的实例化。
在回到AnnotationConfigApplicationContext的构造方法
在这里插入图片描述
看一下new AnnotatedBeanDefinitionReader(this)里面做了什么。
经过一些调用之后最终调用了AnnotationConfigUtils.registerAnnotationConfigProcessors();
在这一步会完成spring中很重要的操作:
在给定的registry(AnnotationConfigApplicationContext)中注册post processors
在这里插入图片描述
完成context的实例化之后,执行context.register(AppConfig.class)
这个也没什么好讲的,就是往context注册一个beandefinition。

执行context.refresh(),这个就比较重要了,进去看一下做了哪些事情。

prepareBeanFactory(beanFactory),在这个方法会配置beanFactory的一些标准化特性
在这里插入图片描述
关于ApplicationContextAwareProcessor参见ApplicationContextAwareProcessor用法解析
做完准备工作之后,执行invokeBeanFactoryPostProcessors(beanFactory),在这个方法会调用所有的BeanFactoryPostProcessor,执行完这个方法后,ConfigurationClassPostProcessor实例就已经放到singletonObjects了,进入这个方法看看:

在这里插入图片描述
invokeBeanFactoryPostProcessors(beanFactory, beanFactoryPostProcessors)方法中定义了两种泛型类型的List:
// 用于保存常规的实现BeanFactoryPostProcessor的
// PostProcessor
List regularPostProcessors

// 保存实现BeanDefinitionRegistryPostProcessor的
// PostProcessor
List registryPostProcessors
首先,先调用实现了PriorityOrdered接口的 BeanFactoryPostProcessor,ConfigurationClassPostProcessor就实现了PriorityOrdered接口。
在这里插入图片描述

在这里插入图片描述
postProcessBeanDefinitionRegistry中调用了processConfigBeanDefinitions(registry)方法,进入这个方法。
在这里插入图片描述
在这里插入图片描述
回到processConfigBeanDefinitions(registry)方法,这时候已经拿到了Configuration配置类的候选者AppConfig,继续往下看
在这里插入图片描述
在这里插入图片描述
中间经过一些转换调用,进入了下面这个方法
在这里插入图片描述
在这里插入图片描述
此处对于@Bean的处理,还没完成beanDefinition的注册,仅仅只是将@Bean 方法保存在AppConfig的成员变量this.beanMethods中,在后续执行processConfigBeanDefinitions(BeanDefinitionRegistry registry)方法中的this.reader.loadBeanDefinitions(configClasses)这一行代码完成beanDefinition的注册。

@Import比较重要,后面在分析
在这里插入图片描述
扫描过程就不接着往下看了,最终会将扫描包下的类注册到beanDefinitionMap

回到上面ConfigurationClassPostProcessor的processConfigBeanDefinitions(BeanDefinitionRegistry registry)
在这里插入图片描述

这里已经完成了invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry)
继续往下执行
在这里插入图片描述
在这里插入图片描述
进入了ConfigurationClassPostProcessor的postProcessBeanFactory()方法
在这里插入图片描述
如果配置类加了@configuration注解,会返回CGLIB代理类,如果没加,返回的是原生的类,有什么作用,后面在讲。

执行完invokeBeanFactoryPostProcessors后,继续往下执行
在这里插入图片描述
TestBeanFactoryPostProcessor没有实现PriorityOrdered和Ordered接口,参见BeanFactoryPostProcessor的简单应用
在这里插入图片描述
完成了我们自定义的TestBeanFactoryPostProcessor的调用。

至此完成了invokeBeanFactoryPostProcessors(beanFactory)的调用,继续往下执行。
在这里插入图片描述
执行完registerBeanPostProcessors(beanFactory)之后,那5个BeanPostProcessor将被注册进来,加入到beanPostProcessor列表中。我们熟悉的AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor实例也被放到了singletonObjects中
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值