说在前面
前期回顾
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 源码解析 更新完毕
源码解析
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