说在前面

前期回顾

sharding-jdbc源码解析 更新完毕

spring源码解析 更新完毕

spring-mvc源码解析 更新完毕

spring-tx源码解析 更新完毕

spring-boot源码解析 更新完毕

rocketmq源码解析 更新完毕

dubbbo源码解析 更新完毕

netty源码解析 更新完毕

spring源码架构更新完毕

spring-mvc源码架构更新完毕

springboot源码架构更新中

github https://github.com/tianheframe

sharding-jdbc源码解析 更新完毕

rocketmq源码解析 更新完毕

seata 源码解析 更新完毕

dubbo 源码解析 更新完毕

netty 源码解析 更新完毕

源码解析

springboot easyexcel实现数据导出成excel表格功能 springboot 导出csv_spring

org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider指示特定模板引擎(如FreeMarker或Thymeleaf)的视图模板的可用性。

boolean isTemplateAvailable(String view, Environment environment,      ClassLoader classLoader, ResourceLoader resourceLoader);

如果给定视图的模板可用,则返回true。

org.springframework.boot.autoconfigure.template.PathBasedTemplateAvailabilityProvider 从路径中查找模板的TemplateAvailabilityProvider实现的抽象基类。

org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider 为JSP视图模板提供可用性信息。

org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider#getResourceName 获取资源名

@Override  public boolean isTemplateAvailable(String view, Environment environment,      ClassLoader classLoader, ResourceLoader resourceLoader) {    if (ClassUtils.isPresent("org.apache.jasper.compiler.JspConfig", classLoader)) {      String resourceName = getResourceName(view, environment);      if (resourceLoader.getResource(resourceName).exists()) {        return true;      }      return new File("src/main/webapp", resourceName).exists();    }    return false;  }

解析模板变量,org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider#getResourceName

private String getResourceName(String view, Environment environment) {    PropertyResolver resolver = new RelaxedPropertyResolver(environment,        "spring.mvc.view.");    String prefix = resolver.getProperty("prefix",        WebMvcAutoConfiguration.DEFAULT_PREFIX);    String suffix = resolver.getProperty("suffix",        WebMvcAutoConfiguration.DEFAULT_SUFFIX);    return prefix + view + suffix;  }

org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider TemplateAvailabilityProvider,为FreeMarker视图模板提供可用性信息。

private List<String> templateLoaderPath = new ArrayList<String>(        Arrays.asList(FreeMarkerProperties.DEFAULT_TEMPLATE_LOADER_PATH));
public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/";

模板加载路径

FreeMarkerTemplateAvailabilityProperties() {      super(FreeMarkerProperties.DEFAULT_PREFIX,          FreeMarkerProperties.DEFAULT_SUFFIX);    }

默认文件名.ftl

org.springframework.boot.autoconfigure.web.ErrorController标记接口,用于指示@Controller用于呈现错误。主要用于知道不需要保护的错误路径。

org.springframework.boot.autoconfigure.web.BasicErrorController基本的全局错误控制器,呈现错误属性。更具体的错误可以使用Spring MVC抽象(例如@ExceptionHandler)或添加servlet容器错误页面来处理。

org.springframework.boot.autoconfigure.web.WebMvcRegistrations 接口来注册WebMvcConfigurationSupport的关键组件,以替代Spring MVC提供的默认组件。所有自定义实例稍后都由Boot和Spring MVC配置处理。应该注册此组件的单个实例,否则就不可能从冗余的MVC组件中进行选择。

RequestMappingHandlerMapping getRequestMappingHandlerMapping();

返回应该由MVC配置使用和处理的定制RequestMappingHandlerMapping。

RequestMappingHandlerAdapter getRequestMappingHandlerAdapter();

返回应该由MVC配置使用和处理的定制RequestMappingHandlerAdapter。

ExceptionHandlerExceptionResolver getExceptionHandlerExceptionResolver();

返回定制的ExceptionHandlerExceptionResolver,它应该由MVC配置使用和处理。

org.springframework.boot.autoconfigure.web.WebMvcRegistrationsAdapter WebMvcRegistrations的一个实现,它使用空方法,允许子类只覆盖它们感兴趣的方法。默认的适配器类实现

org.springframework.boot.autoconfigure.web.ErrorViewResolver 错误页面视图解析器

ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status,      Map<String, Object> model);

解析错误视图

org.springframework.boot.autoconfigure.web.ErrorAttributes提供对可记录或显示给用户的错误属性的访问。

Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes,      boolean includeStackTrace);

返回错误属性的映射。映射可以用作错误页面ModelAndView的模型,也可以作为ResponseBody返回。

Throwable getError(RequestAttributes requestAttributes);

返回错误的基本原因,如果无法提取错误,则返回null。

org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor BeanFactoryPostProcessor的抽象基类,可用于动态声明特定类型的所有bean都应该依赖于一个或多个特定bean。实现了org.springframework.beans.factory.config.BeanFactoryPostProcessor接口。

private final Class extends FactoryBean>> factoryBeanClass;

factoryBeanClass

private final Class> beanClass;

beanClass

private final String[] dependsOn;

依赖的bean名称

@Override  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {    for (String beanName : getBeanNames(beanFactory)) {//      获取名称的BeanDefinition      BeanDefinition definition = getBeanDefinition(beanName, beanFactory);//      获取BeanDefinition的依赖的bean名称      String[] dependencies = definition.getDependsOn();      for (String bean : this.dependsOn) {        dependencies = StringUtils.addStringToArray(dependencies, bean);      }      definition.setDependsOn(dependencies);    }  }

重写org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory方法,处理BeanDefinition的依赖的bean名称

org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer

@Override  public void initialize(ConfigurableApplicationContext applicationContext) {    applicationContext.addBeanFactoryPostProcessor(        new CachingMetadataReaderFactoryPostProcessor());  }

添加CachingMetadataReaderFactoryPostProcessor的BeanFactoryPostProcessor

org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer.CachingMetadataReaderFactoryPostProcessor实现了org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor接口

@Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)        throws BeansException {    }

重写org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory方法,这里不做处理

@Override    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)        throws BeansException {//      注册BeanDefinition      register(registry);//      设置internalConfigurationAnnotationProcessor的beanPostProcessor      configureConfigurationClassPostProcessor(registry);    }

重写org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法,设置internalConfigurationAnnotationProcessor的beanPostProcessor

org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer回调接口,可以由希望通过Jackson2ObjectMapperBuilder进一步定制ObjectMapper的bean实现,该bean保留其默认的自动配置。

org.springframework.boot.autoconfigure.validation.PrimaryDefaultValidatorPostProcessor 如果需要,在自动配置的验证器上启用主标志。

 因为LocalValidatorFactoryBean公开了3个与验证器相关的契约,所以我们只检查缺少javax.validation。只有在没有将Spring的验证器标记为主验证器时,我们才应该将自动配置的验证器标记为主验证器。

实现了org.springframework.context.annotation.ImportBeanDefinitionRegistrar、org.springframework.beans.factory.BeanFactoryAware接口

private ConfigurableListableBeanFactory beanFactory;

beanFactory

@Override  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {    if (beanFactory instanceof ConfigurableListableBeanFactory) {      this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;    }  }

重写org.springframework.beans.factory.BeanFactoryAware#setBeanFactory方法,设置beanFactory

@Override  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,      BeanDefinitionRegistry registry) {//    设置defaultValidator BeanDefinition    BeanDefinition definition = getAutoConfiguredValidator(registry);    if (definition != null) {      definition.setPrimary(!hasPrimarySpringValidator(registry));    }  }

重写org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions方法,设置defaultValidator BeanDefinition

org.springframework.boot.autoconfigure.data.rest.SpringBootRepositoryRestConfigurer 一个存储库reitoryrestconfigurer,它应用spring.data中的配置项。rest命名空间到Spring数据rest。此外,如果有一个Jackson2ObjectMapperBuilder可用,它将用于配置Spring Data REST的ObjectMappers。

org.springframework.boot.autoconfigure.elasticsearch.jest.HttpClientConfigBuilderCustomizer回调接口,可以由希望通过HttpClientConfig进一步定制HttpClientConfig的bean实现。生成器,同时保留默认的自动配置。

org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer 回调接口,可以由希望在缓存管理器完全初始化之前对其进行自定义的bean实现,特别是为了调优其配置。

org.springframework.boot.autoconfigure.web.HttpMessageConverters Bean用于管理Spring引导应用程序中使用的HttpMessageConverters。提供向web应用程序添加和合并其他HttpMessageConverters的方便方法。如果需要,可以使用特定的附加转换器注册此bean的实例,否则将使用默认转换器。注意:默认使用的转换器与标准Spring MVC相同(参见WebMvcConfigurationSupport)。通过对getMessageConverters进行轻微的重新排序,将XML转换器放在列表的后面。

private final List>> converters;

convertersorg.springframework.boot.autoconfigure.BackgroundPreinitializer

private static final AtomicBoolean preinitializationStarted = new AtomicBoolean(      false);

是否是先初始化

private static final CountDownLatch preinitializationComplete = new CountDownLatch(1);

是否初始化完成,这里是用计数器来控制同步的

org.springframework.boot.autoconfigure.domain.EntityScanPackages类,用于存储@EntityScan指定的包供以后参考(例如,通过JPA自动配置)。

private final List packageNames;

扫描的包名

public static void register(BeanDefinitionRegistry registry, String... packageNames) {    Assert.notNull(registry, "Registry must not be null");    Assert.notNull(packageNames, "PackageNames must not be null");    register(registry, Arrays.asList(packageNames));  }

注册BeanDefinition,org.springframework.boot.autoconfigure.domain.EntityScanPackages#register(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.util.Collection)

public static void register(BeanDefinitionRegistry registry,      Collection<String> packageNames) {    Assert.notNull(registry, "Registry must not be null");    Assert.notNull(packageNames, "PackageNames must not be null");//    注册 EntityScanPackages BeanDefinition    if (registry.containsBeanDefinition(BEAN)) {      BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);      ConstructorArgumentValues constructorArguments = beanDefinition          .getConstructorArgumentValues();//      设置第一个构造参数值      constructorArguments.addIndexedArgumentValue(0,          addPackageNames(constructorArguments, packageNames));    }    else {//      创建BeanDefinition,2.5之前用rootBeanDefinition、childBeanDefinition创建有父子关系的BeanDefinition,只有用GenericBeanDefinition,也可以体现父子关系//      也可以用BeanDefinitionBuilder创建用的也是GenericBeanDefinition      GenericBeanDefinition beanDefinition = new GenericBeanDefinition();//      设置beanClass属性      beanDefinition.setBeanClass(EntityScanPackages.class);//      设置第一个构造参数      beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0,          packageNames.toArray(new String[packageNames.size()]));      beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);//      注册BeanDefinition      registry.registerBeanDefinition(BEAN, beanDefinition);    }  }

org.springframework.boot.autoconfigure.domain.EntityScanPackages.Registrar#registerBeanDefinitions

@Override    public void registerBeanDefinitions(AnnotationMetadata metadata,        BeanDefinitionRegistry registry) {//      获取EntityScan注解的BeanDefinition进行注册      register(registry, getPackagesToScan(metadata));    }

获取EntityScan注解指定的BeanDefinition进行注册,org.springframework.boot.autoconfigure.domain.EntityScanPackages.Registrar#getPackagesToScan

private Set<String> getPackagesToScan(AnnotationMetadata metadata) {//      获取EntityScan对象      AnnotationAttributes attributes = AnnotationAttributes.fromMap(          metadata.getAnnotationAttributes(EntityScan.class.getName()));//      获取basePackages属性值      String[] basePackages = attributes.getStringArray("basePackages");//      获取basePackageClasses属性值      Class>[] basePackageClasses = attributes          .getClassArray("basePackageClasses");      Set<String> packagesToScan = new LinkedHashSet<String>();      packagesToScan.addAll(Arrays.asList(basePackages));      for (Class> basePackageClass : basePackageClasses) {//        添加basePackageClasses指定的包名        packagesToScan.add(ClassUtils.getPackageName(basePackageClass));      }      if (packagesToScan.isEmpty()) {        String packageName = ClassUtils.getPackageName(metadata.getClassName());        Assert.state(!StringUtils.isEmpty(packageName),            "@EntityScan cannot be used with the default package");        return Collections.singleton(packageName);      }      return packagesToScan;    }
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(EntityScanPackages.Registrar.class)public @interface EntityScan {

在扫描实体类时配置自动配置使用的基本包。使用@EntityScan将自动配置为:设置扫描JPA实体的包。设置与Neo4J的SessionFactory一起使用的包。设置与Spring Data MongoDB、Cassandra和Couchbase映射上下文一起使用的初始实体集。可以指定basepackageclass()、basePackages()或其别名值()之一来定义要扫描的特定包。如果没有定义特定的包,则使用此注释对类的包进行扫描。

@AliasFor("basePackages")  String[] value() default {};

basePackages()属性的别名。允许更简洁的注释声明,例如:@EntityScan("org.my.pkg")而不是@EntityScan(basePackages="org.my.pkg")。

@AliasFor("value")  String[] basePackages() default {};

扫描实体的基本包。value()是此属性的别名(并且与此属性互斥)。使用basepackageclass()作为基于字符串的包名称的类型安全替代。

Class>[] basePackageClasses() default {};

类型安全的basePackages()替代方案,用于指定要扫描实体的包。将扫描指定的每个类的包。考虑在每个包中创建一个特殊的no-op标记类或接口,这个类或接口除了被这个属性引用之外没有其他用途。

org.springframework.boot.autoconfigure.condition.BeanTypeRegistry实现了org.springframework.beans.factory.SmartInitializingSingleton接口,DefaultListableBeanFactory中包含的bean类型的注册表。提供与ListableBeanFactory类似的功能。getBeanNamesForType(类,boolean, boolean),但基于以下假设,OnBeanCondition对其进行了优化:Bean定义不会更改类型。bean定义不会被删除。bean不会并行创建。

private final DefaultListableBeanFactory beanFactory;

beanFactory

private final Map<String, RootBeanDefinition> beanDefinitions = new HashMap<String, RootBeanDefinition>();

beanDefinitions

static BeanTypeRegistry get(ListableBeanFactory beanFactory) {    Assert.isInstanceOf(DefaultListableBeanFactory.class, beanFactory);    DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory) beanFactory;    Assert.isTrue(listableBeanFactory.isAllowEagerClassLoading(),        "Bean factory must allow eager class loading");//    BeanFactory中不包含BeanTypeRegistry BeanDefinition    if (!listableBeanFactory.containsLocalBean(BEAN_NAME)) {//      创建BeanDefinition,这里用的是RootBeanDefinition      BeanDefinition bd = new RootBeanDefinition(BeanTypeRegistry.class);//      设置BeanDefinition的构造参数      bd.getConstructorArgumentValues().addIndexedArgumentValue(0, beanFactory);//      注册BeanDefinition      listableBeanFactory.registerBeanDefinition(BEAN_NAME, bd);    }    return listableBeanFactory.getBean(BEAN_NAME, BeanTypeRegistry.class);  }

如果不存在BeanTypeRegistry BeanDefinition就进行注册,返回BeanTypeRegistry的对象

org.springframework.boot.autoconfigure.web.WebMvcValidator 一个公开为WebMvc使用的bean的SmartValidator。封装现有的SpringValidatorAdapter实例,以便只公开Spring的验证器类型。这可以防止这样的bean同时公开Spring和JSR-303验证器契约。

实现了org.springframework.context.ApplicationContextAware、org.springframework.beans.factory.InitializingBean、org.springframework.beans.factory.DisposableBean 

@Override  public void setApplicationContext(ApplicationContext applicationContext)      throws BeansException {    if (!this.existingBean && this.target instanceof ApplicationContextAware) {      ((ApplicationContextAware) this.target)          .setApplicationContext(applicationContext);    }  }

重写org.springframework.context.ApplicationContextAware#setApplicationContext方法,设置applicationContext

@Override  public void afterPropertiesSet() throws Exception {    if (!this.existingBean && this.target instanceof InitializingBean) {      ((InitializingBean) this.target).afterPropertiesSet();    }  }

重写了org.springframework.beans.factory.InitializingBean#afterPropertiesSet方法,执行SpringValidatorAdapter的afterPropertiesSet方法

@Override  public void destroy() throws Exception {    if (!this.existingBean && this.target instanceof DisposableBean) {      ((DisposableBean) this.target).destroy();    }  }

执行SpringValidatorAdapter的destory方法

org.springframework.boot.autoconfigure.domain.EntityScanner 一个实体扫描器,它从@EntityScan指定的包中搜索类路径。

private final ApplicationContext context;

context

@SafeVarargs  public final Set> scan(Class extends Annotation>... annotationTypes)      throws ClassNotFoundException {//    获取包名    List<String> packages = getPackages();    if (packages.isEmpty()) {      return Collections.>emptySet();    }    Set> entitySet = new HashSet>();    ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(        false);    scanner.setEnvironment(this.context.getEnvironment());    scanner.setResourceLoader(this.context);    for (Class extends Annotation> annotationType : annotationTypes) {      scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType));    }    for (String basePackage : packages) {      if (StringUtils.hasText(basePackage)) {//        扫描包下的BeanDefinition        for (BeanDefinition candidate : scanner            .findCandidateComponents(basePackage)) {          entitySet.add(ClassUtils.forName(candidate.getBeanClassName(),              this.context.getClassLoader()));        }      }    }    return entitySet;  }

扫描包路径下的BeanDefinition