第10章 后端Web进阶(SpringBoot原理)

发布时间:2026/8/1 10:20:18
第10章 后端Web进阶(SpringBoot原理) 一、配置优先级SpringBoot中支持的三种格式的配置文件哪一种优先级最高呢1、导入项目在项目包的文件资源管理器中粘贴该项目在项目结构中添加该模块的pom.xml依赖文件实现项目的导入2、创建多种配置文件先检查配置文件中的数据库的用户名和密码是否正确项目中原有application.yml配置文件新建application.properties配置文件新建application.yaml配置文件三份配置文件分别创建三份端口号启动项目发现8081端口优先级最高将其注释掉发现使用8083端口号所以优先级application.properties application.yml application.yaml注意虽然springboot支持多种格式配置文件但是在项目开发时推荐统一使用一种格式的配置yml是主流。3、其他配置 文件属性 的方法SpringBoot除了支持配置文件属性配置还支持Java系统属性和命令行参数的方式进行属性配置。Java系统属性 -Dserver.port9000 前面加上-D命令行参数 --server.port10010 前面加上--VM options表示Java系统属性Program arguments表示命令行参数经过测试优先级命令行参数 Java系统属性 配置文件外部配置的属性的优先级高于内部的4、将Java系统属性和命令行参数打包成jar包注意Springboot项目进行打包时需要引入插件spring-boot-maven-plugin基于官网骨架创建项目会自动添加该插件build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins /build项目所依赖的所有jar包都会集中打到这一个jar包双击后打开这个的磁盘目录磁盘目录上运行该目录的cmd只运行配置文件java -jar springboot-web-config-0.0.1-SNAPSHOT.jar加上外部配置运行的java -Dserver.port9000 -jar springboot-web-config-0.0.1-SNAPSHOT.jar --server.port10010二、Bean管理Bean就是IOC容器中所管理的这些对象1、Bean作用域1介绍singleton 容器内同名称的bean只有一个实例单例默认prototype 每次使用该bean时会创建新的实例非单例/多例request 每个请求范围内会创建新的实例web环境中了解session 每个会话范围内会创建新的实例web环境中了解application 每个应用范围内会创建新的实例web环境中了解使用Scope注解来声明bean2测试类测试从DeptController中拿到Bean对象查看是否是单例的输出的都是相同的代表该类中的Bean对象是单例的package com.itheima; ​ ​ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; ​ SpringBootTest class SpringbootWebTests { ​ Autowired private ApplicationContext applicationContext;//IOC容器 Test public void testScope(){ for (int i 0; i 1000; i) { Object deptController applicationContext.getBean(deptController);//IOC容器 System.out.println(deptController); } } }3延迟初始化注意默认singleton的bean在容器启动时被创建可以使用Lazy注解来延迟初始化延迟到第一次使用时。4多例的beanDeptController加上Scope(prototype)//每次请求都会创建新的bean每一次都会新建一个bean对象5使用哪个判断bean是否有状态只需要判断在作用域中是否保存数据无状态的用单例的bean有状态的用多例的bean注意实际开发当中绝大部分的Bean是单例的也就是说绝大部分Bean不需要配置scope属性。6面试题面试题1Spring容器的bean是单例的还是多例的单例的bean是什么时候实例化的?默认是单例的单例的bean默认是项目启动时实例化的通过Lazy可以延迟初始化)面试题2Spring容器的bean是线程安全的吗bean的线程安全取决于bean的状态及bean的作用域单例bean如果是无状态的bean内部不保存任何状态信息则是线程安全的。单例bean如果是有状态的bean内部会保存状态信息多个线程会同时操作该bean时可能会出现数据不一致的问题这样的bean则是线程不安全的。2、第三方bean声明如何将第三方的bean声明为IOC容器里的bean想法加上Component、Controller、Service、Repository注解实际编辑这个类时发现read-only1介绍如果要管理的bean对象来自于第三方不是自定义的是无法用Component及衍生注解声明bean的就需要用到Bean注解。若要管理的第三方bean对象建议对这些bean进行集中分类配置可以通过Configuration注解声明一个配置类。注意如果第三方bean需要依赖其它bean对象直接在bean定义方法中设置形参即可容器会根据类型自动装配。注意通过Bean注解的name或value属性可以声明bean的名称如果不指定默认bean的名称就是方法名。2案例-启动类中声明Bean工具类中该第三方bean没有Component注解没有Autowired为其声明一个有参构造public class AliyunOSSOperator { ​ private final AliyunOSSProperties aliyunOSSProperties; ​ public AliyunOSSOperator(AliyunOSSProperties aliyunOSSProperties) { this.aliyunOSSProperties aliyunOSSProperties; }工具类中AliyunOSSProperties中Data Component//将启动类中的配置属性类交给IOC容器管理 ConfigurationProperties(prefix aliyun.oss) public class AliyunOSSProperties { private String endpoint; private String bucketName; private String region; }在启动类中加入Bean//项目启动时会自动调用该方法将方法的返回值交给IOC容器管理成为IOC容器的Bean对象 public AliyunOSSOperator aliyunOSSOperator(Autowired AliyunOSSProperties aliyunOSSProperties) { return new AliyunOSSOperator(aliyunOSSProperties); }在测试类中加入Test public void testUpload(){ File file new File(D:\\hello.txt); String url aliyunOSSOperator.upload(FileUtil.readBytes(file), file.getName()); System.out.println(url); }启动启动类控制台点击Bean添加依赖重新启动控制台中找到这个bean将启动类中的添加的bean的方法名改为abc修改后发现Bean未指定方法名字默认为方法名实际开发中并不建议在启动类中声明Bean建议对这些Bean进行集中分类配置3案例-集中分类配置在主包下创建config包CommonConfig类将启动类中对该Bean的声明剪切过来并在类上加上Configuration注解Configuration public class CommonConfig { Bean//项目启动时会自动调用该方法将方法的返回值交给IOC容器管理成为IOC容器的Bean对象 public AliyunOSSOperator abc(Autowired AliyunOSSProperties aliyunOSSProperties) { return new AliyunOSSOperator(aliyunOSSProperties); } }什么时候使用Component声明bean什么时候使用Bean注解?一般如果是项目中自定义的类使用component及其衍生注解如果是引入第三方依赖中的类使用Bean注解三、SpringBoot原理-起步依赖原理Spring Framework繁琐依赖、配置Spring Boot简单、快捷SpringBoot为我们提供了两大功能起步依赖、自动配置比如在进行web开发时我们只需要引入web的起步依赖就可以了通过Maven的依赖传递SpringBoot就会把web开发的起步依赖全都传递下来起步依赖的原理就是依赖传递四、SpringBoot原理-自动配置SpringBoot的自动配置就是当spring项目启动后一些配置类、bean对象就自动存入到了IOC容器中不需要我们手动去声明从而简化了开发省去了繁琐的配置操作。比如使用gson的bean功能为转json只需要引入依赖就可以了我们在测试类中注入Gson并使用并不需要配置bean对象原因就是SpringBoot已经将bean对象自动配置好了Autowired private Gson gson; ​ Test public void testGson(){ System.out.println(gson.toJson(Result.success(Hello Gson))); }将依赖自动引入项目是如何自动配置的呢将itheima-utils放入项目的磁盘目录中再在项目结构中导入pom.xml引入依赖dependency groupIdcom.example/groupId artifactIditheima-utils/artifactId version0.0.1-SNAPSHOT/version /dependency这样就实现了工具包的引入1、方案一可以发现工具包的TokenParser已经有Component注解交给IOC容器管理了按理来说可以注入使用了在测试类中注入使用Autowired private TokenParser tokenParser; ​ Test public void testTokenParser(){ tokenParser.parse(); }报错说没有引入该类使用Component注解交给IOC容器使用时并不一定会生效这里面涉及到组件扫描的问题启动类具备组件扫描的功能但是只能扫描启动类所在包及其子包无法扫描到com.example包所以里面的对象不能生效所以我们要手动进行组件扫描在启动类上加上这个注解加上之后启动类自动扫描的包就失效了所以原来的包也要加上ComponentScan(basePackages {com.example, com.itheima})//指定组件扫描的包可以指定多个包用逗号分隔使用繁琐、性能低2、方案二1启动类工具类中的Component注解也可以不用了因为可以导入普通类//自动配置方案二使用Import导入配置类 Import(TokenParser.class)//普通类 Import(HeaderConfig.class)//配置类 Import(MyImportSelector.class)//ImportSelector实现类 - 批量导入2引入的工具类中一定有MyImportSelector导入选择器实现类实现一个方法该方法中返回值是一个数组里面包含了要引入的类public class MyImportSelector implements ImportSelector { public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{com.example.HeaderConfig, com.example.TokenParser}; } }一定有这样一个接口注解EnableHeaderConfig里面引入了Import(MyImportSelector.class)注解。该注解接口供程序员在启动类中批量导入Retention(RetentionPolicy.RUNTIME) Target(ElementType.TYPE) Import(MyImportSelector.class) public interface EnableHeaderConfig { }3优化的启动类所以只需要在启动类上加上EnableHeaderConfig就可以批量导入工具类EnableHeaderConfig SpringBootApplication//具备组件扫描的功能但是只能扫描启动类所在包及其子包 public class SpringbootWebConfigApplication { ​ public static void main(String[] args) { SpringApplication.run(SpringbootWebConfigApplication.class, args); } ​ }这样程序员就不需要知道工具类中有哪些东西了只需要工具类的开发人员编写即可更加方便 优雅4小结1为什么第三方依赖中使用component及其衍生注解声明bean不生效基于Component及其衍生注解声明的bean要想生效需要被组件扫描注解扫描到。2有哪些方案可以使其生效呢通过componentScan注解扫描指定的包通过Import注解将其导入到IOC容器中四种常见方式普通类、配置类、ImportSelector实现类、EnableXxx3、源码跟踪1启动类注解跟踪SpringBootApplication该注解标识在SpringBoot工程引导类上是SpringBoot中最最最重要的注解。封装的注解中前四个是元注解声明注解的注解不需要看看其余三个注解1.SpringBootConfiguration该注解与Configuration注解作用相同用来声明当前也是一个配置类。用于声明第三方bean2.ComponentScan组件扫描默认扫描当前引导类所在包及其子包。3.EnableAutoConfigurationSpringBoot实现自动化配置的核心注解。2启动自动化配置源码跟踪EnableAutoConfiguration封装Import({AutoConfigurationImportSelector.class})查看AutoConfigurationImportSelector自动配置导入选择器实现了DeferredImportSelector继承了ImportSelector导入选择器对于Import({AutoConfigurationImportSelector.class})导入了导入选择器的实现类可以实现批量导入ImportSelector导入选择器中有selectImports方法//将哪些类导入到IOC容器当中类名封装到数组当中 String[] selectImports(AnnotationMetadata importingClassMetadata);AutoConfigurationImportSelector重写了该方法我们看方法的返回值public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!this.isEnabled(annotationMetadata)) { return NO_IMPORTS; } else { AutoConfigurationEntry autoConfigurationEntry this.getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } }追踪getAutoConfigurationEntry查看该方法是如何构建AutoConfigurationEntry对象的我们查看该方法的返回值protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!this.isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } else { AnnotationAttributes attributes this.getAttributes(annotationMetadata); ListString configurations this.getCandidateConfigurations(annotationMetadata, attributes); configurations this.StringremoveDuplicates(configurations); SetString exclusions this.getExclusions(annotationMetadata, attributes); this.checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations this.getConfigurationClassFilter().filter(configurations); this.fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions); } }追踪AutoConfigurationEntryprotected static class AutoConfigurationEntry { private final ListString configurations; private final SetString exclusions; ​ private AutoConfigurationEntry() { this.configurations Collections.emptyList(); this.exclusions Collections.emptySet(); } ​ AutoConfigurationEntry(CollectionString configurations, CollectionString exclusions) { this.configurations new ArrayList(configurations); this.exclusions new HashSet(exclusions); } ​ public ListString getConfigurations() { return this.configurations; } ​ public SetString getExclusions() { return this.exclusions; } }其上有两个属性configurations表示需要自动配置哪些类exclusions表示哪些类要排除出去3找到IOC容器的bean的过程回退一步到getAutoConfigurationEntry再追踪getCandidateConfigurationsprotected ListString getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { ListString configurations ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()) .getCandidates(); Assert.notEmpty(configurations, No auto configuration classes found 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; }断言判断configurations这个集合是否不是空的若是空的会输出后面的提示信息。若不是空的则会加载断言中的这个文件中的所有的类并把类封装到List集合中。集合中封装的就是需要自动配置的类点击该按钮进入jar包找到断言所述文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports在这个文件中配置了类的全类名并且都是AutoConfiguration自动配置所以在启动的时候会加载这一配置文件并把所有的类的字符串加载出来封装到List集合中转化为数组并将数组中的所有的类通过import注解导入到IOC容器中成为IOC容器的bean在项目中使用这些bean就可以直接autowired注入了4bean注入IOC容器的过程可以找到里面的Gson进入AutoConfiguration ConditionalOnClass(Gson.class) EnableConfigurationProperties(GsonProperties.class) public class GsonAutoConfiguration { ​ Bean ConditionalOnMissingBean public GsonBuilder gsonBuilder(ListGsonBuilderCustomizer customizers) { GsonBuilder builder new GsonBuilder(); customizers.forEach((c) - c.customize(builder)); return builder; }进入AutoConfiguration可以发现Configuration说明这也是一个配置类Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Documented Configuration(proxyBeanMethods false) AutoConfigureBefore AutoConfigureAfter public interface AutoConfiguration {所以这些AutoConfiguration都是配置类。在这些配置类中声明了一个个的Bean对象其中就有一个Bean对象是Gson所以可以在项目中直接注入这个Bean就可以直接使用了AutoConfiguration ConditionalOnClass(Gson.class) EnableConfigurationProperties(GsonProperties.class) public class GsonAutoConfiguration { ​ Bean ConditionalOnMissingBean public GsonBuilder gsonBuilder(ListGsonBuilderCustomizer customizers) { GsonBuilder builder new GsonBuilder(); customizers.forEach((c) - c.customize(builder)); return builder; } ​ Bean ConditionalOnMissingBean public Gson gson(GsonBuilder gsonBuilder) { return gsonBuilder.create(); } ​ Bean public StandardGsonBuilderCustomizer standardGsonBuilderCustomizer(GsonProperties gsonProperties) { return new StandardGsonBuilderCustomizer(gsonProperties); }5总结通过将数组中的所有的类通过import注解导入到IOC容器中成为IOC容器的bean注意在低版本(2.7.0以前)的springboot中自动配置类(XxxAutoConfiguration)是定义在spring.factories文件中。这些不会全部注册为IOC容器的bean因为有ConditionalOnMissingBean注解只有符合一定条件才会注册为IOC容器的bean具体注册过程看下一节4、源码跟踪(Conditional)作用按照一定的条件进行判断在满足给定条件后才会注册对应的bean对象到spring IOC容器中。位置方法、类Conditional本身是一个父注解派生出大量的子注解ConditionalOnClass判断环境中是否有对应字节码文件才注册bean到Ioc容器。ConditionalOnMissingBean判断环境中没有对应的bean类型或名称才注册bean到Ioc容器。ConditionalOnProperty判断配置文件中有对应属性和值才注册bean到Ioc容器。当条件不成立时会报错显示没有这样的bean1ConditionalOnClass使用在工具包下的HeaderParser加上注解表示环境中有Jwts就会注册到IOC容器中Bean ConditionalOnClass(name io.jsonwebtoken.Jwts)//条件判断如果类路径下存在io.jsonwebtoken.Jwts类则创建bean public HeaderParser headerParser(){ return new HeaderParser(); }web主项目中已有Jwts依赖所以HeaderParser将会注册到IOC容器中!--JWT令牌-- dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.9.1/version /dependencytest包中可以注册并运行Autowired private HeaderParser headerParser; ​ Test public void testHeaderParser(){ headerParser.parse(); }2ConditionalOnMissingBean的使用环境中不存在该类自动注册到IOC容器中了Bean ConditionalOnMissingBean//条件判断如果容器中不存在HeaderParser bean则创建bean public HeaderParser headerParser(){ return new HeaderParser(); }3ConditionalOnProperty的使用配置文件中存在myname属性且值为itheima则创建beanBean ConditionalOnProperty(name myname, havingValue itheima)//条件判断如果配置文件中存在myname属性且值为itheima则创建bean public HeaderParser headerParser(){ return new HeaderParser(); }在application.yml中加入这样的配置myname: itheima4源码中的bean加的是ConditionalOnMissingBean环境中没有这样的bean会创建出来Bean ConditionalOnMissingBean public GsonBuilder gsonBuilder(ListGsonBuilderCustomizer customizers) { GsonBuilder builder new GsonBuilder(); customizers.forEach((c) - c.customize(builder)); return builder; }5小结1.Conditional及其衍生注解的作用是什么满足给定条件后注册对应的bean对象到SpringIoc容器中。2.Conditional及其衍生注解可以作用在什么地方方法上针对于当前这个方法声明的bean类上针对于这个类中所有的方法声明的bean3.自己定义自动配置类的核心是什么如何完成自动配置定义自动配置类将自动配置类配置在META-INF/spring/org.springframework.boot.autoconfigure.Autoconfiguration.imports文件中5、自定义starter-分析1starter两部分功能starter包含两部分的功能起步依赖、自动配置起步依赖依赖传递自动配置依赖下以autoconfigure为结尾的依赖场景在实际开发中经常会定义一些公共组件提供给各个项目团队使用。而在SpringBoot的项目中一般会将这些公共组件封装为SpringBoot的starter包含了起步依赖和自动配置的功能。2依赖的功能以Spring-boot开头的依赖是SpringBoot官方提供的依赖以其他名称开头的依赖是其他技术提供的依赖以autoconfigure结尾的依赖是自动配置功能以starter结尾的依赖是起步依赖功能引入依赖时只需要引入starter依赖即可根据依赖传递会自动传递引入autoconfigure依赖3将阿里云OSS打包成依赖传统的阿里云引入方法引入四五个依赖--根据阿里云的SDK编写入门程序--将入门程序改造成文件上传的工具类--将工具类交给IOC容器管理声明为IOC容器的bean对象--在项目中使用需求自定义aliyun-oss-spring-boot-starter完成阿里云oss操作工具类Aliyunossoperator的自动配置。目标引入起步依赖引入之后要想使用阿里云oss注入Aliyunossoperator直接使用即可。步骤:1.创建aliyun-oss-spring-boot-starter模块2.创建aliyun-oss-spring-boot-autoconfigure模块在starter中引入该模块3.在aliyun-oss-spring-boot-autoconfigure模块中定义自动配置的功能并定义自动配置文件META-INF/spring/xxxx.imports6、自定义starter-实现1创建模块创建模块不需要引入依赖直接创建项目即可只留一个pom文件将父工程的版本改为3.2.10。删掉用不到的配置只保留最精简的?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.2.10/version relativePath/ !-- lookup parent from repository -- /parent groupIdcom.aliyun.oss/groupId artifactIdaliyun-oss-spring-boot-starter/artifactId version0.0.1-SNAPSHOT/version namealiyun-oss-spring-boot-starter/name descriptionaliyun-oss-spring-boot-starter/description ​ properties java.version17/java.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter/artifactId /dependency /dependencies ​ /project创建aliyun-oss-spring-boot-autoconfigure项目步骤和上面一样但是保留src目录删除启动类、test包和application.properties2引入autoconfigure模块在aliyun-oss-spring-boot-starter中引入aliyun-oss-spring-boot-autoconfigure的依赖dependency groupIdcom.aliyun.oss/groupId artifactIdaliyun-oss-spring-boot-autoconfigure/artifactId version0.0.1-SNAPSHOT/version /dependency3autoconfigure中定义自动配置功能添加阿里云依赖!--阿里云OSS依赖-- dependency groupIdcom.aliyun.oss/groupId artifactIdaliyun-sdk-oss/artifactId version3.17.4/version /dependency ​ dependency groupIdjavax.xml.bind/groupId artifactIdjaxb-api/artifactId version2.3.1/version /dependency dependency groupIdjavax.activation/groupId artifactIdactivation/artifactId version1.1.1/version /dependency !-- no more than 2.3.3-- dependency groupIdorg.glassfish.jaxb/groupId artifactIdjaxb-runtime/artifactId version2.3.3/version /dependency将以前写的工具类的AliyunOssOperator类和AliyunOSSProperties类放到资源目录下Data需要引入为了减少依赖的引入我们直接提供get、set方法和toString方法Component和Autowired也不要了改成这样public class AliyunOSSOperator { ​ private AliyunOSSProperties aliyunOSSProperties; //提供有参构造 public AliyunOSSOperator(AliyunOSSProperties aliyunOSSProperties) { this.aliyunOSSProperties aliyunOSSProperties; }此时这两个类已经不是IOC容器的bean了如何实现自动配置功能添加AliyunOSSAutoConfiguration类实现自动配置EnableConfigurationProperties(AliyunOSSProperties.class) Configuration public class AliyunOSSAutoConfiguration { ​ Bean ConditionalOnMissingBean public AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties aliyunOSSProperties) { return new AliyunOSSOperator(aliyunOSSProperties); } }4定义自动配置文件在resource目录下创建目录META-INF/spring目录下创建org.springframework.boot.autoconfigure.AutoConfiguration.imports文件把AliyunOSSAutoConfiguration的全类名拷贝到该文件中这样自定义starter就配置好了我们来测试一下5导入测试项目资源管理器粘贴springboot-autoconfiguration-test项目并在项目结构中导入pom文件引入aliyun-oss-spring-boot-starter的依赖dependency groupIdcom.aliyun.oss/groupId artifactIdaliyun-oss-spring-boot-starter/artifactId version0.0.1-SNAPSHOT/version /dependency可以发现阿里云的所有依赖已全部引入控制层Autowired这个aliyunOSSOperatorRestController public class UploadController { ​ Autowired private AliyunOSSOperator aliyunOSSOperator; ​ PostMapping(/upload) public String upload(MultipartFile image) throws Exception { //上传文件到阿里云 OSS String url aliyunOSSOperator.upload(image.getBytes(), image.getOriginalFilename()); System.out.println(上传文件到阿里云OSS成功url url); return url; } ​ }并在application.yml中配置一下阿里云的访问信息# 阿里云OSS aliyun: oss: endpoint: https://oss-cn-beijing.aliyuncs.com bucketName: java-ai-swb region: cn-beijing6测试在apifox中上传图片控制台和响应体都获取了该图片的访问路径状态码返回200说明当前的bean在引入starter的依赖后已经完成了自动配置只要注入该工具类就可以直接基于OSS实现文件上传五、注解//Bean //每次请求都会创建新的bean Scope(prototype) //延迟初始化 -- 延迟到第一次使用的时候再来创建这个bean Lazy //引入第三方bean Bean //声明bean的配置类 Configuration //指定组件扫描包 ComponentScan //导入普通类 Import(TokenParser.class) //自动导入工具类指定的类 EnableHeaderConfig //导入选择器 MyImportSelector.class //直接导入注解里面封装了要导入的bean EnableHeaderConfig //启动类中的注解 //该注解与Configuration注解作用相同用来声明当前也是一个配置类。用于声明第三方bean SpringBootConfiguration //组件扫描默认扫描当前引导类所在包及其子包。 ComponentScan //SpringBoot实现自动化配置的核心注解。 EnableAutoConfiguration //导入了导入选择器 Import({AutoConfigurationImportSelector.class}) //导入bean的配置注解 AutoConfiguration //条件判断注册bean对象 //本身是一个父注解派生出大量的子注解 Conditional //判断环境中是否有对应字节码文件才注册bean到Ioc容器。 ConditionalOnClass //判断环境中没有对应的bean类型或名称才注册bean到Ioc容器。 ConditionalOnMissingBean //判断配置文件中有对应属性和值才注册bean到Ioc容器。 ConditionalOnProperty