终于, 有一天我也来看 Spring 的源码了, 看了一阵之后感觉心情那叫一个舒畅, 对 Spring 底层的实现也有了进一步的了解, 最直观的感受就是 Spring 的命名风格很赞, 很长, 真的长到使人见名知意, 闲言少叙, 开始整理笔记了
程序的入口
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
跟进这个 AnnotationConfigApplicationContext()程序的启动入口, 注解配置的应用上下文. 主要做了下面的三件事
调用本类无参构造方法
调用
register(annotatedClasses)
将我们传递进来的配置类注册进 BeanFactory 的 BeanDefinitionMap
刷新容器
- public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
- this();
- register(annotatedClasses);
- refresh();
- }
创建 BeanFactory
首先调用本类的无参构造方法,, 通过上图, 可以看到, AnnotationConfigAllicationContext 的父类是 GenericApplicationContext 但是, 在执行本类的无参构造方法时会先执行父类的无参构造方法. 它父类的无参构造方法我贴在下面, 就做了一件事, 初始化了 Spring 的 BeanFactory, 没错就是 Spring 的 Bean 工厂, 由于两者的继承关系, 我们就任务, AnnotationConfigApplicationContext 的 Bean 工厂被初始化了
- public GenericApplicationContext() {
- this.beanFactory = new DefaultListableBeanFactory();
- }
创建
AnnotatedBeanDefinitionReader
加载
接着回到这个构造方法的源码我贴在下面, 这个构造方法主要做了两件事
为应用的上下文创建 reader 读取器, 读取被添加了注解的类信息
实例化了一个 Scanner, 这个 Scanner 可以用去做包扫描的工作, 但是 Spring 根据我们的配置信息去进行包扫描的工作时, 并没有使用这个扫描器, 而是自己 new 了一个, 当前的扫描器可以理解成是方便程序员使用而创建的
- public AnnotationConfigApplicationContext() {
- this.reader = new AnnotatedBeanDefinitionReader(this);
- this.scanner = new ClassPathBeanDefinitionScanner(this);
- }
下面跟进 AnnotatedBeanDefinitionReader 扫描器的创建过程, 经过几个没有重要逻辑的方法, 我们会进入 registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source), 下面是源码: 这算是 Spring 初始化的一个小高潮了!!!, 为啥这样说呢? 因下面的逻辑中, 为 Spring 初始化过程中, 构建 BeanFactory 提供了几个开天辟地性质的 RootBeanDefinition``
首先是在为 BeanFactory 添加了两个大组件
AnnotationAwareOrderComparator
用于解析 @Order 和 @Priorty 注解
ContextAnnotationAutowireCandidateResolver
提供了懒加载的支持
然后就是往 BeanFactory 中的 BeanDefinitionMap 中添加了 6 个 RootBeanDefinition
- ConfigurationClassPostProcessor
- AutowiredAnnotationBeanPostProcessor
- ...
- public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
- BeanDefinitionRegistry registry, @Nullable Object source) {
- // 得到 bean 工厂
- DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
- if (beanFactory != null) {
- if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
- // 给 Bean 工厂添加原材料
- // AnnotationAwareOrderComparator 主要能解析 @Order 注解和 @Priority
- beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
- }
- if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
- // ContextAnnotationAutowireCandidateResolver 提供处理懒加载 (Lazy) 相关的功能
- beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
- }
- }
- // 作用是方便传递参数 BeanDefinitionHolder
- Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
- // BeanDefinition 的注册, 这里很重要, 需要理解注册每个 bean 的类型
- // 就是判断工厂中有没有包含 CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME 名称的 bean, Spring 在启动时, 工厂肯定是空的返回 false , 加上! 表示 ture
- if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {//configuration_annotation_processor_bean_name
- // 注意: 下面的 ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor, 间接实现了 BeanFactoryPostProcessor bean 工厂的后置处理器
- // RootBeanDefinition 可以理解成 描述 Spring 内部类的 Definition
- // 除了通过 AnnotationedBeanDefinitionReader 把 加上了注解的类加载成 bean, 下面的第二种方式, 通过 new RootBeanDefinition, 进而将 XXX.class 起来注册进 bean 工厂
- // 这是使用第二种方式, 通过 new Spring 自己实现的 BeanDefinition 接口的类, 将 java 转换成 Bean 然后 put 进 BeanFactory 的 BeanDefinitionMap 中
- // 下面的 111-666 就是最先放置进去的 6 个 Spring 的 RootBean 对象
- // ---111---------------------------
- RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
- def.setSource(source);
- // 跟进去 registerPostProcessor
- beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- //AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor
- //MergedBeanDefinitionPostProcessor 最终实现了 BeanPostProcessor
- // ---222---------------------------
- RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- // ---333---------------------------
- RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
- if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- // ---444---------------------------
- RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
- if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition();
- try {
- def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
- AnnotationConfigUtils.class.getClassLoader()));
- }
- catch (ClassNotFoundException ex) {
- throw new IllegalStateException(
- "Cannot load optional framework class:" + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
- }
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
- // ---555---------------------------
- RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
- }
- if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
- // ---666---------------------------
- RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
- }
- return beanDefs;
- }
上面的代码中有来如下两个亮点:
亮点 1:RootBeanDefinition
首先涉及到的知识点就是, Spring 有哪几种方式将对象转成 BeanDefinition? 其实是有两种, 第一种就是让 Spring 通过 Scanner 去扫描包解析程序员提供的添加了注解的类, 这是个自动完成的过程, 第二种就是 Spring 通过 new RootBeanDefinition 等诸多的 BeanDefinition 接口的实现类, 然后将 Spring 原生的对象当成参数传递进去进而转换成 BeanDefinition, 当然, Spring 在这里选择的就是第二种方法
亮点 2:
ConfigurationClassPostProcessor
这个类很牛, 为什么这么说呢? 先看一下他的继承类图
没错, 他是 6 个 RootBeanDefinition 中唯一的一个实现 BeanFactoryPostProcessor 的, 其他的五个 RootBeanDifinition 实现的都是 BeanPostProcessor, 其实也不用懵逼, 只要我们整明白这里说的 BeanPostProcessor 和 BeanFactoryPostProcessor 的作用就好了, 然后在这里我用下面的两个模块解释
BeanPostProcessor
接口的抽象方法源码如下:
- public interface BeanPostProcessor {
- @Nullable
- default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
- @Nullable
- default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
- }
两个方法名, 见名知意: 第一个会在 对象的 constructor 之后, init()方法之前调用
第二个会在 init()方法之后调用
但是, 大家可以发现, 它的调用时机都是在构造方法执行之后进行拦截, 这时候 BeanDefinition 已经被实例化了
- BeanFactoryPostProcessor
- @FunctionalInterface
- public interface BeanFactoryPostProcessor {
- void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
- }
它就比较厉害了, 这也是 Spring 牛的地方, 它不仅仅会替我们维护这些 Bean, 而且还通过当前的 BeanFactoryPostProcessor, 为程序员开放一个缺口, 让程序员可以参与到 Bean 的创建过程中来, 为什么这样说呢, 其实大家可以看到, 它唯一的抽象方法中的入参位置上是谁? 没错, 就是 BeanFactory, Bean 工厂都给我们了, 那不是想干啥干啥?
其次, 它的作用时机是执行 Bean 的构造方法之前
最直接的应用场景: 当一个单例的 Bean 依赖 多例的 Bean 时, 我们多次通过 应用的上下文获取出来的单例 bean 的 hashcode 都是唯一的这没错, 但是紧接着打印它依赖的多例对象的 hashcode 同样是相同的, 这种单例失效的问题, 就可以根据这个知识点从容解决
前面说的 ConfigurationClassPostProcessor 就是 BeanFactoryPostProcessor 的实现类, 并且它也不辱使命, 完美的使用作用时机不同的特点, 在程序员提供的配置类的构造方法调用之前, 就先入为主, 围棋生成了 cglib 代理对象
接着看代码, 回到上面的代码, 我们看如何将 RootBeanDefinition 注册进 BeanFactory, 我从上面截取一行代码放在这里
- // 跟进去 registerPostProcessor
- beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
跟进这个 registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)
- private static BeanDefinitionHolder registerPostProcessor(
- BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
- definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- // registerBeanDefinition()
- registry.registerBeanDefinition(beanName, definition);
- return new BeanDefinitionHolder(definition, beanName);
- }
我们关注这个 registry.registerBeanDefinition(beanName, definition); , 可以看到, 其实这个 registerBeanDefinition()是 BeanDefinitionRegistry 的抽象方法, 我们要找的是它的实现类, 那问题来了, 是谁实现他呢? 可以回到博客顶部, 看看第一个图, 没错 Spring 的 BeanFactory, 也就是 DefualtListableBeanFactory 实现了这个接口, 虽然有点意外, 一个工厂竟然还是一个注册器, 但是这也是事实情况, 看看这个工厂是如何做的吧 . 原函数很长, 我截取了部分源码如下: 它的解释我写在源码的下面
- public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
- throws BeanDefinitionStoreException {
- ...
- else {
- // 添加进入容器中, 最终的结果就是, 这个 map 中存在哪些类, Spring 的 IoC 中就有哪些类
- // Still in startup registration phase
- this.beanDefinitionMap.put(beanName, beanDefinition);
- // 单独使用一个 list 存放名字
- this.beanDefinitionNames.add(beanName);
- this.manualSingletonNames.remove(beanName);
- }
- this.frozenBeanDefinitionNames = null;
- }
- if (existingDefinition != null || containsSingleton(beanName)) {
- resetBeanDefinition(beanName);
- }
可以看到, 他将一开始的 6 个 RootBeanDefinition 全都都 put 进了一个 map 中, 下面这个 map
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
key 就是 beanName, value 就是 BeanDefinition
这也是迄今为止我们遇到的第一个 map, 这个 map 是 BeanFactory 的一个组件, 但是它可不是传说中的 IoC 容器, 大家也看到了它里面存放的是 BeanDefinition, 而不是 Bean
将配置类注册进 BeanFactory
回到一开始 AnnotationConfigApplicationContext 的 register(annotatedClasses); 方法, 然后一路往下跟, 会经过几个没有什么重要逻辑的方法, 然后来到这里
- public void register(Class<?>... annotatedClasses) {
- for (Class<?> annotatedClass : annotatedClasses) {
- // 继续跟进去
- registerBean(annotatedClass);
- }
- }
通过上面的代码, 我们可以回想, annotatedClasses 这个可变长度的参数, 其实就是我们在 AnnotationConfigApplicationContext 中传递进来的主配置类 MainConfig, 也就是说, 这个主配置类是可以存在多个的
接着往下跟
- <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
- @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
- // 可以将当前类理解成一个方便参数传递的封装类
- // 意为: 被加上注解的通用的 BD
- // 将传递进来的 主配置类封装进 这个 AnnotatedGenericBeanDefinition
- AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
- if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
- return;
- }
- abd.setInstanceSupplier(instanceSupplier);
- // 解析出它的元数据
- ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
- // 设置它的作用域
- abd.setScope(scopeMetadata.getScopeName());
- // 名称生成器, 目的是为 BeanDefinition 取个名字, 因为这个 BD 最终被存放到一个 map 中,
- // 默认情况下 @Configuration(value = "XXX") 这个 value 有值, 就是使用这个当成名字
- // 都这就使用 类名首字母小写当成名字
- String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
- // 处理 bean 上的通用注解, @Lazy @Dependon @Primary role 等
- AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
- if (qualifiers != null) {
- for (Class<? extends Annotation> qualifier : qualifiers) {
- if (Primary.class == qualifier) {
- abd.setPrimary(true);
- }
- // 懒加载, 前面加过
- else if (Lazy.class == qualifier) {
- abd.setLazyInit(true);
- }
- else {
- abd.addQualifier(new AutowireCandidateQualifier(qualifier));
- }
- }
- }
- for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
- customizer.customize(abd);
- }
- // 理解成方便参数传递的封装类
- BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd,beanName);
- definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
- // 我们关注的重点, 注册 BeanDefinition
- BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
- }
上面的函数的主要作用如下: 将我们通过 AnnotationConfigApplicationContext 构造函数传递进来的主配置类封装进了 AnnotatedGenericBeanDefinition 中, 然后解析它身上的其他注解完成属性的赋值
接着跟进 registerBeanDefinition()方法
- public static void registerBeanDefinition(
- BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
- throws BeanDefinitionStoreException {
- // 再来这个方法之前封装了一个 difinitionHolder , 然后在这里又把它拆分开传递给了下面的函数
- // Register bean definition under primary name.
- String beanName = definitionHolder.getBeanName();
- // 在当前的 BeanDefinitionReaderUtils 中使用
- registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
- // Register aliases for bean name, if any.
- String[] aliases = definitionHolder.getAliases();
- if (aliases != null) {
- for (String alias : aliases) {
- registry.registerAlias(beanName, alias);
- }
- }
- }
继续跟进
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
于是有回到了上面注册 6 大 RootBeanDefinition 的逻辑中, 将我们的主配置类注册进 BeanFactory 的 BeanDefinitionMap 中
未完待续...
来源: https://www.cnblogs.com/ZhuChangwu/p/11674684.html