关于java:SpringBoot-SpringBootApplication

8次阅读

共计 4536 个字符,预计需要花费 12 分钟才能阅读完成。

SpringBoot

SpringBoot 是 Java 利用的开发框架,基于 Spring4.0 设计,继承了 Spring 框架原有的优良个性,还并通过简化配置来进一步优化了 Spring 利用的整个搭建和开发过程,SpringBoot 通过集成大量的框架,很好的解决了依赖包版本抵触,以及援用不稳定性等问题

SpringBoot 个性

  1. 创立独立的 Spring 利用
  2. 内嵌 Tomcat 或 Jetty 等 Servlet 容器,利用打包后即可间接运行
  3. 提供一系列预设配置来简化配置
  4. 尽可能主动配置 Spring 容器与三方类库
  5. 提供可用于生产的个性,如度量、运行状况检查和内部化配置
  6. 不须要代码生成,不须要 XML 配置

主动拆卸

主动拆卸是为了从 spring.factories 文件中获取到对应须要进行主动拆卸的类,并生成相应的 Bean 对象,而后将它们交给 spring 容器来治理嘛,主动拆卸是 SpringBoot 的外围,咱们只有引入一个 starter 组件依赖就能实现主动拆卸

依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.3</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

启动类

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);
    }
}

@SpringBootApplication

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

由源码可知,@SpringBootApplication 理论是由 3 个要害的注解组成

  1. @SpringBootConfiguration
  2. @EnableAutoConfiguration
  3. @ComponentScan

@SpringBootConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {// 内容省略}

由源码可知,@SpringBootConfiguration 实际上就是一个 @Configuration 注解,就是为了让以后类作为一个配置类交由 Spring 的 IOC 容器进行治理

@ComponentScan

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan  {// 内容省略}

由源码可知,@ComponentScan 等价于在 xml 文件中配置 context:component-scan,SpringBoot 会默认扫描以后类所在的包及其子包中的所有标注了 @Component,@Service,@Controller 等注解的类

@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {// 内容省略}

由源码可知,@EnableAutoConfiguration 是由 @AutoConfigurationPackage 与 @Import 组成的注解,而 AutoConfigurationImportSelector 正是主动拆卸的外围;AutoConfigurationImportSelector 实现了顶层接口 ImportSelector,在 selectImports 办法中,首先判断 SpringBoot 是否开启主动配置,如开启则进一步获取须要主动拆卸的类

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}
    AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
    return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    configurations = removeDuplicates(configurations);
    Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    checkExcludedClasses(configurations, exclusions);
    configurations.removeAll(exclusions);
    configurations = getConfigurationClassFilter().filter(configurations);
    fireAutoConfigurationImportEvents(configurations, exclusions);
    return new AutoConfigurationEntry(configurations, exclusions);
}

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
            getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you"
            + "are using a custom packaging, make sure that file is correct.");
    return configurations;
}

其中的重点就在 SpringFactoriesLoader.loadFactoryNames 这一行代码中

public final class SpringFactoriesLoader {

/**
 * The location to look for factories.
 * <p>Can be present in multiple JAR files.
 */
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);

static final Map<ClassLoader, Map<String, List<String>>> cache = new ConcurrentReferenceHashMap<>();

private SpringFactoriesLoader() {}

至此已能够看出,为何 SpringBoot 的依赖中会存在.factories 文件,loadFactoryNames 办法会去 META-INF/spring.factories 文件中依据 EnableAutoConfiguration 的全限定类名获取到咱们须要导入的类,而 EnableAutoConfiguration 类的全限定类名为
org.springframework.boot.autoconfigure.EnableAutoConfiguration

@AutoConfigurationPackage

@AutoConfigurationPackage 注解会将增加该注解的类所在的 package 作为主动配置 package 进行治理,也就是说当 SpringBoot 利用启动时,默认会将启动类所在的 package 作为主动配置的 package

总结

  • SpringBoot 是基于 Spring 的框架
  • SpringBoot 预置了许多依赖,并简化了 Spring 原有的配置,使开发更加简略快捷
  • SpringBoot 通过 AutoConfigurationImportSelector 与 META-INF/spring.factories 省去了一些类的配置过程,实现了主动拆卸
正文完
 0