Spring核心源码深度解析(三) 初始源码

Spring 源码测试实例

一个注解配置类,在com包里有一个User接口,两个实现了User接口的方法(提示:从本章开始,建议读者边看边实操)


image

测试类,笔者将以AnnotationConfigApplicationContext
这个注解类作为入口对源码进行深度分析


image

Spring 源码分析

进入笔者将以AnnotationConfigApplicationContext的构造方法


image

注意细节AnnotationConfigApplicationContext继承了GenericApplicationContext


image

所以会优先执行GenericApplicationContext的默认构造器,并且会创造一个叫DefaultListableBeanFactory的这么个类,
image

这个类分量很大,是Spring的核心类,我们点开DefaultListableBeanFactory这个类,
image

我们一步一步向上跟踪会发现它实现了BeanFactory,所以这就我们一直说的Bean工厂、Bean工厂,实际上Bean工厂也就是在这个时候就创建了,当然这个类还要其他重要的功能,笔者暂时放一放,咱们继续往下走,执行完父类的构造器后,现在开始执行自己的构造器了

public AnnotationConfigApplicationContext() {   
    //这个reader顾名思义是一个读取器,而且十分重要,稍后会说明为什么重要  
    this.reader = new AnnotatedBeanDefinitionReader(this);  
    //这个scanner说实话没有什么卵用,因为在spring内部自己new了一个扫描器,而不是用的这个对象,而这个类是交给程序员手动获取的,基本用不到  
    this.scanner = new ClassPathBeanDefinitionScanner(this);
    }   

如上图所示:AnnotationConfigApplicationContext构造器创建了一个读取器,一个扫描器,而这个scanner为什么由上述注释所写的后期我们在扫描的时候证明。进入this.reader=new AnnotatedBeanDefinitionReader(this); 这行代码调入
image

然后构造器相互调用最终调用这个构造器

image

进入AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
里面又是委托模式,继续渗入registerAnnotationConfigProcessors(registry, null);
最终进入核心方法registerAnnotationConfigProcessors()这个方法大概就做了两件事情,获取之前创建的DefaultListableBeanFactory,然后往里面装一些工具组件,包含排序组件、转换器组件、以及4个特别特别重要的后置处理器。分别是


1、ConfigurationClassPostProcessor
2、AutowiredAnnotationBeanPostProcessor
3、CommonAnnotationBeanPostProcessor
4、EventListenerMethodProcessor

在registerAnnotationConfigProcessors()涉及到Spring后置处理器和BeanDefinition,下面会进行简要分析

Spring后置处理器

什么是后置处理器,笔者这里对Spring其中一个顶层的后置处理器进行详细说明


image

看了上面的注释,读者可能还是比较懵逼,我们在实践一下


image

我们实现了BeanFactoryPostProcessor拿到了ConfigurableListableBeanFactory,然后我们从工厂可以获取某一个类的BeanDefinition(注意:很多小伙伴一个有一个误区,不知道什么是对象什么是Bean,笔者认为Bean一定是对象,对象不一定是Bean,而对象成为Bean的条件就是完成Spring的整体生命周期),拿到从工厂获取的BeanDefinition,是不是就可以进行修改这个BeanDefinition,再结合笔者上文后置处理器的注释,相信这个时候读者应该对后置处理器有一定初步的认识,当然这个时候小伙伴们可能就要问了,我拿到BeanDefinition有什么用?看下图,
image

这里并没有对Spring Bean流程详细介绍,只是对整体流程描述了大概。如果还是不明白我们在后面会详细说明后置处理器的作用。

BeanDefinition

在think in java的作者提出,一切皆为对象,一切皆可抽象,而BeanDefinition正是Spring抽象设计的精髓,回到上文笔者强调Bean和对象不是同一个概念,Spring认为仅仅是java自带的对象是不能满足于我所需求的,就好比单例、Lazy等一些特性无法满足,所以Spring定义一个BeanDefinition作为对象的抽象,来实现对象的抽象,(当然BeanDefinition的分量很高,笔者在后面会更详细的介绍它具体的作用)明白这点后我们回到代码:

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
      BeanDefinitionRegistry registry, @Nullable Object source) {

    //从注册器获取beanFactory
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
      //这里是判断beanFactory有没有排序的工具
      if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
        beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
      }
      //这里是判断beanFactory有没有转换器
      if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
        beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
      }
    }
    //之后你会看到很多BeanDefinitionHolder,这个BeanDefinitionHolder其实没什么作用,就是一个
    //封装了BeanDefinition的map,而BeanDefinition是对spring将要实例化对象的一个缓存,
    //类似于对象的class,只是功能比class更丰富
    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    //重点来了,这里涉及到了一个概念叫BeanFactoryPostProcessor,详细看接口
    //registerPostProcessor这个方法就是将RootBeanDefinition放到工厂的map对象去
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    //下面是注册五个类,但有一个类会被忽略,所以总共只注册了五个类
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      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)) {
      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)) {
      RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
    }

    return beanDefs;
  }

这里其实就是获取前面创建的工厂,然后向工厂装一些组件,目的就是初始化工厂,然后再为工厂创建Spring自定义的后置处理器作为BeanDefinition存起来,然后返回,这是我们的this已经执行完毕,回到这个图。

image

咱们再看一遍注释,相信读者大致能理解
我们再看register方法->this.reader.register(componentClasses);->registerBean(componentClass);->doRegisterBean(beanClass, null, null, null);

<T>  void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
    //这里可以看到使用AnnotatedGenericBeanDefinition去创建的 后面会通过这个类的父接口去做一些判断
    //此外在这个创建注解BD的时候就对内部的元注解进行初始化,自己有标识了注解
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
    }
    abd.setInstanceSupplier(instanceSupplier);
    //获取作用域元数据
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    //这里是对Config配置类进行注解信息的设置,Lazy,Primary,DependsOn等等
    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);
    //将bd注册到我们的BeanFactory去
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  }

其实我们可以看到核心代码就是最下面一句, BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);将我们的配置类或普通类注册到BeanDefinitionMap集合里。而前面只是做一些判断,比如是不是Lazy,Primary,DependsOn,有没有Supplier等

深度分析Spring核心方法refresh()

refresh()目录
//这个方法没什么用,里面都是一些系统环境设置
prepareRefresh();
// 这里只是将beanFactory拿出来
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 对beanFactory添加一些处理器,并设置一些属性
prepareBeanFactory(beanFactory);
// 空方法
postProcessBeanFactory(beanFactory);
// 这里是执行实现了BeanFactoryPostProcessor这个接口的子类
// 重点就是spring自己的一个类
// 秒扫出要实例化的类,放进工厂的beanDef里面,这里只是放的bd并不是真正的实例化对象invokeBeanFactoryPostProcessors(beanFactory);
//注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// Initialize message source for this 
context.initMessageSource();
// 创建ApplicationEventMulticaster这么一个类initApplicationEventMulticaster();
//空方法  
onRefresh();
// 注册监听器
registerListeners();
//完成对bean的创建finishBeanFactoryInitialization(beanFactory);
// publish corresponding event.
finishRefresh();

我们可以看到Spring在refresh方法里面做了很多很多的事情,我们逐步分析:

prepareRefresh():这个方法并不用太关注,这是Spring记录一些系统日期、日志之类的,我们直接跳过。

obtainFreshBeanFactory():这个方法只是将创建的工厂拿出来给后续的方法作为参数利用

image

prepareBeanFactory():


protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 这里是对beanFactory设置一些工具类,后面用到再说,先跳过
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 添加一个ApplicationContextAwareProcessor后置处理器
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //设置一些需要忽略的类,避免重复,这里就是避免从面部传进这些class影响Spring内部操作
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

看这句代码,beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));、进入ApplicationContextAwareProcessor 找到下面代码


image

可以看到里面有大量的回调接口。如果没搞明白我们写了例子


image
image

可以看出,我们可以通过回调拿到Spring内部的对象,这里可以结合再一个实例,单例对象的属性注入原型对象,就需要这种方式解决,而这个对象那里来的呢,咱们回到源码:

  //解决依赖注入来源问题
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // 注册一个用来销毁Bean的后置处理器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // Register default environment beans.
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
  }

这里就是Spring内部注册的对象,这里涉及到一个数据源的问题,我们会在依赖注入的环节单独详细说明笔者暂且可以认为这些对象没有经过Spring的生命周期,但可以提供依赖注入。

postProcessBeanFactory()

image

空壳方法,这里猜测是Spring为自己预留的拓展功能。接下来的方法较为重要,笔者打算单独开一章节详细分析

本小节总结:
1、创建一个工厂 this.beanFactory = new DefaultListableBeanFactory();
2、创建一个读取器 this.reader = new AnnotatedBeanDefinitionReader(this);
3、对beanFactory添加一些组件工具,添加4个后置处理器
4、通过之前创建的读取器把传进来的类转换为BeanDefinition注册到工厂里。

5、Spring在自己内部设置了一些数据源信息比如ApplicationContext、Resourse等

6、添加了一个ApplicationContextAwareProcessor后置处理器提供Aware回调

7、忽略一些Spring内部关键的类,防止外部修改或影响了Spring内部的核心类

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343