乐趣区

关于springboot:SpringBoot开发笔记2-springboot原理初探解析helloworld

2.1 父依赖: starter-parent

helloworld查看依赖: 我的项目依赖了 spring-boot-stater-parent:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
</dependency>

spring-boot-stater-parent点进去, 外面还依赖了个parent:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.3.2.RELEASE</version>
</parent>

spring-boot-dependencies再点进去:

一大堆 properties

一大堆 dependencies

可见:

spring-boot-dependencies 才是 springboot 所有依赖真正管理者;

2.2 导入的依赖: starter-web

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId> 
</dependency>

点进去: spring-boot-starter-web 帮咱们导入了 web 我的项目所依赖的依赖项:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.3.2.RELEASE</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
    <version>2.3.2.RELEASE</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>2.3.2.RELEASE</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.8.RELEASE</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.8.RELEASE</version>
    <scope>compile</scope>
  </dependency>
</dependencies>
  1. spring-boot-starter
  2. spring-boot-starter-json
  3. spring-boot-starter-tomcat
  4. spring-web
  5. spring-webmvc

starter: spring boot 帮忙治理依赖资源;

spring 提供了一系列 starter: mail/web/jpa/mq…

2.3 @SpringBootApplication 注解

注解类:

//....SpringBootApplication...
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration // 1
@EnableAutoConfiguration // 2
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

.....
    
//....SpringBootConfiguration...
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration    // 3
public @interface SpringBootConfiguration {
    
.....
    
//....Configuration...
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component // 4
public @interface Configuration {

次要注解类:

2.4 SpringBootApplication 之 @SpringBootConfiguration

SpringBootConfiguration能够看到, 有 Configuration所以:

2.4.1 申明 Application 类为一个配置类

SpringBootApplication -> SpringBootConfiguration -> Configuration -> Component

注解了 @SpringBootApplication 就有了 @SpringBootConfiguration;

就有了 @Configuration 的性能; 即: 此类是配置类!

就有了 @Component 的性能;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration // 继承了 Component
public @interface SpringBootConfiguration {

下面阐明: HelloApplication.java 注解了 @SpringBootApplication 它就是一个配置类, 能够被 AnnotationConfigApplicationContext加载扫描起来!

2.5 SpringBootApplication 之 @EnableAutoConfiguration

按需主动注入 spring.factories 组件

2.5.1 EnableAutoConfiguration 注解原理

  1. 门路: org.springframework.boot.autoconfigure.EnableAutoConfiguration
  2. 此类所属 jar 包 spring-boot-autoconfigure.jar 目录下有 META-INF/spring.factories文件, 内容如下: 能够这么了解: 上面所有类都是配置类, 作用都相似于写一个 @Configuration的类, 在其中初始化相应所须要的的 @Bean;

    # Initializers
    org.springframework.context.ApplicationContextInitializer=\
    org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
    org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
    
    # Application Listeners
    org.springframework.context.ApplicationListener=\
    org.springframework.boot.autoconfigure.BackgroundPreinitializer
    
    # Auto Configuration Import Listeners
    org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
    org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
    
    # Auto Configuration Import Filters
    org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
    org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
    org.springframework.boot.autoconfigure.condition.OnClassCondition,\
    org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition
    
    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
    org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
    ............ 省略 100 多个....
    
    # Failure analyzers
    org.springframework.boot.diagnostics.FailureAnalyzer=\
    org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\
    org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
    org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\
    org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
    org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\
    org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\
    org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer
    
    # Template availability providers
    org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
    org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
    org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
    org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
    org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
    org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider
    

2.5.2 EnableAutoConfiguration 的继承关系

//....EnableAutoConfiguration...
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage // 5
@Import(AutoConfigurationImportSelector.class) // 6
public @interface EnableAutoConfiguration {}

//....AutoConfigurationPackage...
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)     // 7
public @interface AutoConfigurationPackage {}


// ...Registrar...
// ...ImportBeanDefinitionRegistrar...
/**
 * {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
 * configuration.
 */
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
    }

    @Override
    public Set<Object> determineImports(AnnotationMetadata metadata) {return Collections.singleton(new PackageImports(metadata));
    }

}
// ImportBeanDefinitionRegistrar 能够在 spring 容器 bean 初始化的时候注入组件到容器中

// 6 处是一个 ImportSelector

// 7 处是一个ImportBeanDefinitionRegistrar

这两处都是往容器中注册 bean, 具体参见笔记:

spring 注解驱动开发 -(5) 向 Spring 容器中注册组件的办法

ImportBeanDefinitionRegistrar 能够在 spring 容器 bean 初始化的时候注入组件到容器中: 在这里打断点能够看到: 会把 com.niewj.springboot 包目录注册进去; 这样, 此包下所有子包中的 spring 注解的类就都会被扫描, 并初始化注册到 spring 容器的上下文;

这样的话, spring 容器在启动容器的时候, 就会按需加载 spring-boot-autoconfigure.jar 包下的 META-INF/spring.factories 中配置的加载类; 达到主动配置注入 bean 到容器中的成果(目标就是不便开发, 不须要可怜的程序员一个一个写 @Configuration 的类, 而后本人写 @Bean 的办法注册组件) 这种机制就是 SPI 深刻了解 SPI 机制

退出移动版