初探SpringBoot
pom.xml
1.父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.1.RELEASE</version>
</parent>
spring-boot-starter-parent 的父项目是 spring-boot-dependencies
spring-boot-dependencies 才是真正管理Spring Boot应用里面的所有依赖版本,是Spring Boot的版本管理中心
以后我们导入依赖默认是不需要写版本;但是没有在dependencies里面管理的依赖自然需要声明版本号
2、启动器
spring-boot-starter-XXX:就是XXX的场景启动器;并为我们自动加载了XXX模块正常运行所需要的依赖组件
Spring Boot将所有功能场景都抽取了出来,做成了一个个的场景启动器(starts);需要什么功能就导入什么功能的场景启动器,这个启动器就会将当前场景需要的依赖都导入进来
<!-- 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.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.3.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.3.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
主程序类、主入口类
@SpringBootApplication
public class SpringBootConfigAutoConfigApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootConfigAutoConfigApplication.class, args);
}
}
结构总览
@SpringBootApplication
@SpringBootConfiguration
@Configuration
@Component
@EnableAutoConfiguration
@AutoConfigurationPackage
@Import(AutoConfigurationPackages.Registrar.class)
@Import(AutoConfigurationImportSelector.class)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
@SpringBootApplication 标识在某个类上,表明该类是springboot的主配置类,通过启用该类的main方法来启动SpringBoot应用
@SpringBootConfiguration 标识在某个类上,表明这是一个springboot配置类
@Configuration 表明标识的类是配置类,其对应的就是spring的xml配置类
@Component 表明标识的类是容器中的一个组件
@EnableAutoConfiguration 开启自动配置功能;以前我们需要手动编写的东西,springboot已经为我们自动配置好了
@AutoConfigurationPackage 自动配置包;将主配置类(由@SpringBootApplication标注的类)所在的包及其该包下所有的子包下的所有组件扫描到spring容器中
@Import(AutoConfigurationPackage.Registat.class) 向容器中导入组件,导入的组件由AutoConfigurationPackages这个类的Registrar方法决定
@Import(AutoConfigurationSelector.class) 向容器中导入组件,导入的组件由AutoConfigurationSelector这个类决定
@ComponentScan() 自动扫描符合要求的组件,并添加到ioc容器中
@SpringBootApplication
标注在某个类上说明这个类是Spring Boot的主配置类,Spring Boot通过运行这个类的main方法来启动Spring Boot应用。
@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 {
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
@SpringBootConfiguration
标识在某个类上,表明这是一个springboot配置类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
@Configuration
spring底层注解;表明标识的类是配置类,其对应的就是spring的xml配置类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(annotation = Component.class)
String value() default "";
boolean proxyBeanMethods() default true;
}
@Component
spring底层注解;表明标识的类是容器中的一个组件
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
@EnableAutoConfiguration
开启自动配置功能;以前我们需要手动编写的东西,springboot已经为我们自动配置好了
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
@AutoConfigurationPackage
自动配置包;将主配置类(由@SpringBootApplication标注的类)所在的包及其该包下所有的子包下的所有组件扫描到spring容器中
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
@Import(AutoConfigurationPackages.Registrar.class)
向容器中导入组件,导入的组件由AutoConfigurationPackages.Registrar.class决定
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));
}
}
@Import(AutoConfigurationImportSelector.class)
向容器中导入组件,导入的组件由AutoConfigurationImportSelector.class决定
将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中
那么这些自动配置类的作用是什么呢?
这些自动配置类的作用就是:给容器中导入这个场景需要的所有组件,并配置好这些组件。所以说有了这些自动配置类以后,就免去了我们手动编写配置注入功能组件等工作了
总结:
Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作,以前我们需要自己配置的东西,自动配置类都帮我们配置好了
@ComponentScan()
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
自动扫描符合要求的组件,并将其加入到 IOC 容器中