SpringBoot中“@SpringBootApplication“自动配置原理《第七课》
了解几个注解的概念下面的是核心注解
第一点:@SpringBootApplication介绍:
在SpringApplication类中有SpringApplication和Run方法他们的作用是什么呢!
解析注解:@SpringBootApplication 结论是
在SpringBoot学习中:@SpringBootApplication = (默认属性)@Configuration + @EnableAutoConfiguration + @ComponentScan。
@EnableAutoConfiguration:能够自动配置spring的上下文,试图猜测和配置你想要的bean类,通常会自动根据你的类路径和你的bean定义自动配置。
@ComponentScan:会自动扫描指定包下的全部标有@Component的类,并注册成bean,当然包括@Component下的子注解@Service,@Repository,@Controller。
@Configuration的注解类标识这个类可以使用Spring IoC容器作为bean定义的来源。@Bean注解告诉Spring,一个带有@Bean的注解方法将返回一个对象,该对象应该被注册为在Spring应用程序上下文中的bean。
第二点:public @interface SpringBootApplication
@Target({ElementType.TYPE})ElementType 提供了一个简单的分类:注释可能出现在Java程序中的语法位置(这些常量与元注释类型(@Target)一起指定在何处写入注释的合法位置)
@Retention(RetentionPolicy.RUNTIME)RetentionPolicy,与元注释(@Retention)一起指定注释要保留多长时间
@Documented Documented注解表明这个注释是由 javadoc记录的,在默认情况下也有类似的记录工具。 如果一个类型声明被注释了文档化,它的注释成为公共API的一部分。
@Inherited @inherite 源码
然后,我们打开 inherited 的源码,可以看到:
(1)该注解作用于整个程序运行中(@Retention(RetentionPolicy.RUNTIME);
(2)该注解只能修饰注解(@Target({ElementType.ANNOTATION_TYPE})),因此,它是一个元注解。
@SpringBootApplication:组合注解,包括以下注解。
@SpringBootConfiguration 配置注解,底层其实也是@Configuration注解,只不过在SpringBoot工程中更推荐使用@SpringBootConfiguration来替代
@EnableAutoConfiguration 启动自动配置,根据所依赖的Jar包自动配置相关配置项。(后续会继续解释)
@ComponentScan 扫描配置,SpringBoot默认会扫描启动类所在的同级包及其子包。
@SpringBootConfiguration:springboot的配置
@Configuration:spring配置类
@Component:说明这也是spring的组件
@EnableAutoConfiguration::自动配置
@AutoConfigurationPackage:自动配置包
@Import(AutoConfigurationPackages.Registrar.class):自动配置‘包注册’
@Import(AutoConfigurationImportSelector.class):自动配置选择
@EnableAutoConfiguration 本文章以这个注解贯通自动配置原理 其他的细节下篇文章解释为了读者能看懂原理本文参用图片的方式来介绍
package com.bing.springboot0906;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Springboot0906Application {
public static void main(String[] args) {
SpringApplication.run(Springboot0906Application.class, args);
}
}
@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}
)}
)
上面的代码啥意思这里不介绍了上面有具体的说明
@Import(AutoConfigurationImportSelector.class):自动配置选择 点击下面的代码 AutoConfigurationImportSelector你会发现下面类中的代码 完全是考验Java的基础的时候了。
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {}
在这个类中找到下面的图片标记的内容
ListString> configurations = this.getCandidateConfigurations(annotationMetadata,
attributes);//获取所有的配置 点击getCandidateConfigurations会跳转到一个方法中去
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));
ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
上面的代码 获取候选配置
List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(),
点击这个进去:SpringFactoriesLoader
public final class SpringFactoriesLoader {
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所有 自动配置都是在启动的时候扫描并加载: spring . factories所有的自动配置类都在这里面,但是不一-定生效, 要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!
springboot在启动的时候,从类路径下/META-INF/ spring . factories获取指定的值;
将这些自动配置的类导入容器,自动配置就会生效,帮我进行自动配置!
以前我们需要自动配置的东西,现在springboot帮我们做了
整合javaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.2.0.RELEASE.jar这个包下
它会把所有需要导入的组件,以类名的方式返回,这些
组件就会被添加到容器;
容器中也会存在非常多的xxAutoConfiguration的文件(@Bean),就是这些类给容器中导入了这个场景需要的所有组件;并自动配置,@Configuration ,JavaConfig!
有了自动配置类,免去了我们手动编写配置文件的工作!
核心要义 继承继承在继承 封装封装在封装
实现了SpringBoot自动配置