spring源码深度分析

spring源码深度分析

1.写在前面

本文是对spring源码的深度分析,阅读起来有一定难度,如果对spring应用不太熟练的话,更是难上加难。分析源码是一件枯燥乏味的事情,需要极大的耐心,在这篇的时候也是经历了很大的痛苦,耗费很大精力,前后花了大致一个月的时间。文章很长,我知道不会有很多人看到最后,但是我相信看到最后的一定能有所收获。阅读本文章要对照源码,最好是版本也一致,文章不会贴出所有的源码细节,并且文章不具备跳转,调试的条件,这在集成开发环境是很方便的。

2.搭建环境

新建maven工程,引入如下依赖即可

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
</dependencies>

新建两个类,启动容器,最基本的spring容器就自动了。

@Configuration
public class AppConfig {
   
   

}

public class TestBean {
   
   

    public static void main(String[] args) {
   
   
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

    }
}

3.源码分析

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   
   
   this();
   register(componentClasses);
   refresh();
}

代码逻辑比较清晰,分别为

  • 创建并初始化容器

  • 将启动类注入到容器

  • 刷新容器

2.1 创建并初始化容器

public AnnotationConfigApplicationContext() {
   
   
   this.reader = new AnnotatedBeanDefinitionReader(this);
   this.scanner = new ClassPathBeanDjavaefinitionScanner(this);
}

主要是两个步骤:

  • 创建注解的BeanDefinition读取器
  • 创建Java类路径定义的扫描器

2.1.1 创建注解的BeanDefinition读取器

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
   
   
   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   Assert.notNull(environment, "Environment must not be null");
   this.registry = registry;
    
   //处理@Conditional注解类,@Conditional注解是按条件注册bean,是springboot实现自动配置的
   //的重要基础之一,这里不详细说明,有机会在springboot原理分析中详细介绍
   this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
   AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

下面主要看registerAnnotationConfigProcessors的逻辑。

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

   //提取beanFactory
   DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
   if (beanFactory != null) {
   
   
      if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
   
   
         //AnnotationAwareOrderComparator类实现了对bean的@Ordered和@Priority注解处理逻辑,可以比较bean的优先级
         beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
      }
      if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
   
   
         //ContextAnnotationAutowireCandidateResolver实现通过@Autowired注解,依赖其他bean的逻辑,在bean寻找并注入依赖时调用,后面会有涉及
         beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
      }
   }

   //下面的逻辑就是初始化几个spring注解实现的核心bean,spring容器内置的几个bean,就在这里注入到容器,他们的名字都以internal开头,
   //但实现的机制不一样,有的实现BeanDefinitionRegistryPostProcessor接口,有的实现BeanPostProcessor接口,
   //就是说调用这些类的方法的时机不一样,这点很重要
   Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

   //ConfigurationClassPostProcessor注入到容器中,这里我们要关注类本身实现的功能和spring容器什么时候调用的该类的方法。
   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, javaEVENT_LISTENER_FACTORY_BEAN_NAME));
   }

   return beanDefs;
}
2.1.1.1 ConfigurationClassPostProcessor类

这个类处理当bean的方法中标记了@Bean注解或者类标记了@Configuration注解。

通过查看源码可以得出,该类实现了BeanDefinitionRegistryPostProcessor接口,我们只需要关注下面的两个方法。这两个方法是在容器将所有bean加载为BeanDeifinition后,bean实例化前执行的,目的就是在bean实例化前给个机会修改BeanDefinition的内容,进而影响bean实例化的,具体的用法参考BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor用法与原理,并且postProcessBeanDefinitionRegistry方法会先执行,postProcessBeanFactory后执行,这里的逻辑会在实际调用的时候分析。

2.1.1.2 AutowiredAnnotationBeanPostProcessor类

这个类处理@Autowired,@Value,@Inject注解,实现类依赖自动注入的解析逻辑。这个类间接的实现了BeanPostProcessor接口,基于BeanPostProcessor后置处理原理,实现原理参考BeanPostProcessor后置处理器原理与应用

2.1.1.3 CommonAnnotationBeanPostProcessor类

解析@PreDestroy,@PostConstruct,@Resource等注解,也是个实现BeanPostProcessor的接口。

2.1.1.4 PersistenceAnnotationBeanPostProcessor类

这个类与jpa访问数据库相关,这里不做介绍。

2.1.1.5 EventListenerMethodProcessor和DefaultEventListenerFactory类

这两个之所以在一起介绍,主要是跟spring的事件监听机制有关,请参考spring的ApplicationEvent事件监听机制原理与应用

这几个spring容器启动时就注册类,实现类基于注解的spring容器的基本功能,这几个bean有什么作用,在哪调用的,会在后面的分析中说明,当前只需要知道这几个基础类是在启动时注册的即可。

2.1.2 创建Java类路径定义的扫描器

当实例化AnnotationConfigApplicationContext传入的是包名时,ClassPathBeanDefinitionScanner这个类会识别包中所有标记了@Component,@Repository,@Service,@Controller主机的类,注册到容器中。

2.2 将启动类注入到容器

从register(componentClasses);开始分析。这里的componentClasses参数是一个可变参数列表,可以传入多个启动配置,本例子只传入了一个AppConfig空配置类。跟踪代码进入到下面方法;

public void register(Class<?>... componentClasses) {
   
   
   //遍历处理每一个配置列
   for (Class<?> componentClass : componentClasses) {
   
   
      registerBean(componentClass);
   }
}

省略了几个中间的方法传递调用直接进入处理逻辑

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
      @Nullable BeanDefinitionCustomizer[] customizers) {
   
   

   //将配置类封装成基于注解的BeanDefinition
   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    
   //这里判断当前bean是否存在@Conditional注解,如果不满足条件得话就直接跳过,不处理。通常主配置类不带条件,就是说这里不会跳过。
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
   
   
      return;
   }

   abd.setInstanceSupplier(supplier);
   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);//解析scope
   abd.setScope(scopeMetadata.getScopeName());//默认scope时singleton
   //获取默认beanName,类名首字母小写
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); 

   //解析通用得注解属性,包括@Lazy,@Primary,@DependsOn,@Role,@Description
   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
   
   if (qualifiers != null) {
   
   //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));
         }
      }
   }
   if (customizers != null) {
   
     //customizers=null
      for (BeanDefinitionCustomizer customizer : customizers) {
   
   
         customizer.customize(abd);
      }
   }

   //注册到容器中
   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

2.3 刷新容器

代码入口refresh();这个方法时整个spring的核心,也是最复杂的,涉及的内容很多,这里的每一个方法基本上代表一个spring的功能,逻辑比较清晰,下面逐个分析,整个代码在同步块中。

public void refresh() throws BeansException, IllegalStateException {
   
   
   synchronized (this.startupShutdownMonitor) {
   
   
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
   
   
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         initMessageSource();

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         finishRefresh();
      }

      catch (BeansException ex) {
   
   
         if (logger.isWarnEnabled()) {
   
   
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
   
   
         // Reset common introspection caches in Spring's core, since wejava
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

2.3.1准备刷新(prepareRefresh())

做一下初始化准备,没有什么重要的逻辑。

2.3.2 获取BeanFactory(obtainFreshBeanFactory())

获取BeanFactory,本案例通过注解启动,obtainFreshBeanFactory()方法会执行GenericApplicationContext类的refreshBeanFactory() 方法,这个方法除了置了一个标记,没有其他逻辑。

2.3.3 准备BeanFactory(prepareBeanFactory(beanFactory))

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   
   
   // Tell the internal bean factory to use the context's class loader etc.
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
   //解析依赖时,忽略这几个接口
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   //与上面的忽略相反,这几个bean是可以被依赖注入的
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   //注册一个事件监听器后置处理器
   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容器注册了几个基础的bean,这几个bean实现spring的以下功能机制的。

2.3.4 空方法(postProcessBeanFactory(beanFactory))

空方法,用于子类实现扩展。

2.3.5 调用BeanFactoryPostProcessor的处理逻辑(invokeBeanFactoryPostProcessors(beanFactory))

这个方法执行时,容器中的bean还没有被实例化,容器中存储的都是代表bean的BeanDefinition,这个方法就是针对BeanDefinition集合处理。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   
   
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
   
   
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

进入PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法。这里的详细逻辑我在BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor用法与原理的原理分析部分详细分析过,请移步。

2.3.6 注册BeanProcessor后置处理器(registerBeanPostProcessors(beanFactory))

注册BeanProcessor到容器,并不是调用BeanProcessor中的方法,注册的源码分析在BeanPostProcessor后置处理器原理与应用中的原理实现中有介绍,这里不重复。

2.3.7 初始化消息源(initMessageSource())

这部分与spring的核心关联不大,省略。

2.3.8 初始化事件广播器(initApplicationEventMulticaster())

spring的ApplicationEvent事件监听机制原理与应用的事件发布原理章节中有介绍

2.3.9 空方法(onRefresh())

2.3.10 注册事件监听器(registerListeners())

protected void registerListeners() {
   
   
   // Register statically specified listeners first.
   for (ApplicationListener<?> listener : getApplicationListeners()) {
   
   
      getApplicationEventMulticaster().addApplicationListener(listener);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let post-processors apply to them!
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String listenerBeanName : listenerBeanNames) {
   
   
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }

   // Publish early application events now that we finally have a multicaster...
   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
   
   
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
   
   
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}

正常的事件监听器都是在BeanProcessor中注册的,这里注册的事件监听器是特殊的,在容器启动时就注册的,还没到容器初始化bean。还有一个逻辑是

如果是early事件,这里直接就发布事件了。

2.3.11 实例化bean(finishBeanFactoryInitialization(beanFactory))

在这个方法里会实例化,初始化所有的不是懒加载的bean。这个过程相当复杂,耐心看下去。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   
   
   // Initialize conversion service for this context.
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
   
   
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }

   // Register a default embedded value resolver if no bean post-processor
   // (such as a PropertyPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   if (!beanFactory.hasEmbeddedValueResolver()) {
   
   
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
   
   
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   beanFactory.freezeConfiguration();

   // Instantiate all remaining (non-lazy-init) singletons.
   beanFactory.preInstantiateSingletons();
}

我们关注最后一行代码,上面的逻辑暂时忽略。其实我们看spring的源码主要关注重要的逻辑,主要功能的实现思路,没必要过分关注实现的所有细节,因为对于任何框架来说,代码量巨大,没有那么多精力充分阅读所有的实现细节。

public void preInstantiateSingletons() throws BeansException {
   
   
   if (logger.isTraceEnabled()) {
   
   
      logger.trace("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   for (String beanName : beanNames) {
   
   
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);  //合并beanDefinition
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
   
     //实例化的前提是:不是抽象类,是单例的,不是懒加载的
         if (isFactoryBean(beanName)) {
   
     //判断工厂bean
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值