1. 创建一个maven项目。pom.xml文件中添加如下的内容。
spring-boot-starter-parent 才能继承父项目中所有的依赖。 其父项目为spring-boot-starter-dependencies, 定义好了组件版本、组件坐标、插件管理。 帮我们管理了springboot中的所有依赖版本,解决了版本冲突的问题。叫做版本仲裁中心
spring-boot-starter-xxx. 以spring-boot-starter-web为例,其中定义好了web开发时所需的大部分依赖。 帮我们整合了第三方库,做了默认配置。需要修改的话到application.properties中修改
plugin: 生成的jar包能都用java -jar独立运行
spring-boot-configuration-processor: 在编写配置文件的时候有自动提示。 IDEA的Annotation Processors 要勾选Enable annotation procession
org.springframework.boot spring-boot-starter-parent2.3.3.RELEASE org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-configuration-processortrue org.springframework.boot spring-boot-devtoolstrue org.springframework.boot spring-boot-maven-plugin2.3.3.RELEASE
2. 编写controller,标记RequestMapping() 指定映射路径
3. SpringBoot启动入口, 使用@SpringBootAppication注解标记。在类中运行springApplication.run()
4. 在Resoures文件夹下加上配置文件 application.properties, 可以配置一些项目属性,比如端口等
5. 创建springBoot父项目。创建好一个maven项目,在该maven项目中创建modules。要在父项目的pom中加上
查看启动类上的注解@SpringBootApplication
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited
@SpringBootConfiguration *****等同与@Configuration,既标注该类是Spring的一个配置类
@EnableAutoConfiguration *****SpringBoot自动配置功能开启
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {...}
按住Ctrl点击查看注解@EnableAutoConfiguration。 告诉SpringBoot去开启自动配置类,会自动加载自动配置类,{AutoConfigurationimportSelector}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited
@AutoConfigurationPackage \将当前所在包路径存到basePackage中供内部使用
@import({AutoConfigurationimportSelector.class})
\导入了AutoConfigurationimportSelector类
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class>[] exclude() default {};
String[] excludeName() default {};
}
AutoConfigurationimportSelector 去meta-INF/spring.factories中加载类
其中,SpringFactoriesLoader.loadFactoryNames 方法的作用就是从
meta-INF/spring.factories文件中读取指定类对应的类名称列表。
文件存在大量的以AutoConfiguration为结尾的类名称,
这些类就是存有自动配置信息的类,
而SpringApplication在获取这些类名后再加载
例如:ActiveMQAutoConfiguration
@Configuration(
proxyBeanMethods = false
)
@AutoConfigureBefore({JmsAutoConfiguration.class})
@AutoConfigureAfter({JndiConnectionFactoryAutoConfiguration.class})
@ConditionalOnClass({ConnectionFactory.class, ActiveMQConnectionFactory.class})
@ConditionalOnMissingBean({ConnectionFactory.class})
@EnableConfigurationProperties({ActiveMQProperties.class, JmsProperties.class})
*******该注解很重要。springBoot会将类ActiveMQProperties【ActiveMQ的属性类】
中的属性和前缀为spring.activemq配置文件中的默认值一一对应【映射】起来
@import({ActiveMQXAConnectionFactoryConfiguration.class, ActiveMQConnectionFactoryConfiguration.class})
public class ActiveMQAutoConfiguration {
public ActiveMQAutoConfiguration() {
}
}
用@import()导入了AutoConfigurationimportSelector.
该类继承了DeferredimportimportSelector类。
会调用getimportGroup()返回的类,如果返回类实现了Group接口,
会调用Group类的Selectimportorf方法。
拿其中一个举例子HttpEncodingAutoConfiguration
@Configuration(
proxyBeanMethods = false
)
@EnableConfigurationProperties({ServerProperties.class})
\每个自动配置都有一个自动配置xxxProperties属性类
\还有Condition注解,满足条件才会将自动配置类注入到IoC容器中
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(
prefix = "server.servlet.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {}
依赖中有autoconfiguration包。作用????????
三. SpringBoot概览SpringBoot是Spring的一站式解决方案,主要用来简化Spring使用,提供了各种启动器,简化了配置,容易上手。
优点:
1. 快速 构建 一个独立的 Spring 应用程序 ; 2. 嵌入的 Tomcat 、 Jetty 或者 Undertow,无须部署 WAR 文件; 3. 提供starter POMs来简化Maven配置和减少版本冲突所带来的问题; 4. 对Spring和第三方库提供默认配置,也可修改默认值,简化框架配置; 5. 提供生产就绪型功能,如指标、健康检查和外部配置; 6. 无需配置XML,无代码生成,开箱即用; 四. SpringBoot配置文件SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。
SpringBoot默认会从Resources目录下加载application.properties或application.yml(application.yaml)文件。
application.properties文件是键值对类型的文件,YML文件是以数据为核心的,比传统的xml方式更加简洁。
SpringBoot的配置文件,主要的目的就是对默认配置信息进行修改的,但在配置时的key从哪里去查询呢?我们可以查阅SpringBoot的官方文档
文档URL:
https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#common-application-properties
配置文件与属性值映射: 将配置文件的值注入到Bean对应的属性中
1.可以通过@Value注解将配置文件中的值映射到一个Spring管理的Bean的字段上,不需要字段提供setter.
2.@ConfigurationProperties(prefix="配置文件中的key的前缀")可以将配置文件中的配置自动与实体进行映射。但需要字段必须提供set方法。
@Value获取值和@ConfigurationProperties获取值比较 3. @PropertySource :加载指定的配置文件; 4. @importResource :导入Spring的配置文件,让配置文件里面的内容生效; Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别; 想让Spring的配置文件生效,加载进来;@importResource标注在一个配置类上配置文件的读取顺序
在spring-boot-starter-parent的pom文件中,
**/application*.yml **/application*.yaml **/application*.properties
所以,配置文件的读取顺序为上述。同时读取,配置文件之间为互补关系。
配置文件一般是在resources根目录下。优先级由低到高如下:
1. classpath根目录下的 2. classpath根config/ 3. 项目根目录: 如果当前项目是继承/耦合 关系maven项目的话,项目根目录=父maven项目的根目录 4. 项目根目录/config 5. 命令行启动指定的直接子目录 /config Profile文件 不同的环境需要不同的配置环境;同一个位置下profile优先级较高application.properties **** spring.profiles.active=prod 指定当前配置文件为生产环境的配置文件
application-dev.properties ***开发的配置文件
application-prod.properties ***生产环境的配置文件
五. 一些面试题1. SpringBoot中devtools热部署
1.1 添加依赖
org.springframework.boot spring-boot-devtoolstrue
1.2修改IDEA配置
(1)File-Settings-Compiler-Build Project automatically (2)ctrl + shift + alt + / ,选择Registry,勾上 Compiler autoMake allow when app running 六. 常见注解 七. SpringBoot启动原理 1 调用SpringApplication.run启动springboot应用 SpringApplication.run(Application.class, args); 2. 创建SpringApplication, 通过 SpringFactoriesLoader.loadFactoryNames(type, classLoader) 加载spring-factories文件中特定的类 (new SpringApplication(primarySources)).run(args); 3.运行run方法 (new SpringApplication(primarySources)). run(args);public ConfigurableApplicationContext run(String... args) {
*****springBoot启动耗时******
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
*******去spring.factroies中读取了SpringApplicationRunListener 的组件, 就是用来发布事件或者运行监听器*****
SpringApplicationRunListeners listeners = this.getRunListeners(args);
*****发布1.ApplicationStartingEvent事件,在运行开始时发送*****
listeners.starting();
Collection exceptionReporters;
try {
*****根据命令行参数 实例化一个ApplicationArguments*****
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
*****预初始化环境: 读取环境变量,读取配置文件信息(基于监听器)*
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
*****创建SpringApplicationContext*****
context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
****预初始化spring上下文**
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
*****加载spring ioc 容器 【相当重要】 由于是使用AnnotationConfigServletWebServerApplicationContext 启动的spring容器所以springboot对它做了扩展: 加载自动配置类:invokeBeanFactoryPostProcessors , 创建servlet容器onRefresh
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
--->this.refresh(context)
---> AbstractApplicationContext.invokeBeanFactoryPostProcessors(beanFactory);
--->PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
--->invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
--->PostProcessorRegistrationDelegate.postProcessor.postProcessBeanDefinitionRegistry(registry); postProcessor就包含 ConfigurationClassPostProcessor ,implenment
--->ConfigurationClassPostProcessor 。processConfigBeanDefinitions(registry); //处理各种配置类,没有@Configuration立即返回。解析@Configuration注解。通常是我们的主配置类
--->。。。--->ConfigurationClassParser.doProcessConfigurationClass() 解析各类注解 @PropertySource @ComponentScan @import @importResource @Bean
---> ConfigurationClassParser.processimports() 在解析import注解时,就得到AutoConfigurationimportSelector名称,然后实例化成selector Bean
if (selector instanceof DeferredimportSelector) { //如果是
this.deferredimportSelectorHandler.handle(configClass, (DeferredimportSelector) selector);
}
else {
String[] importClassNames = selector.selectimports(currentSourceClass.getmetadata());
Collection importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
processimports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
ConfigurationClassPostProcessor BeanDefinitionRegistryPostProcessor——动态注册Bean到Spring容器_跨语言,跨平台,跨应用-CSDN博客
加载spring-factories文件 SpringFactoriesLoader.loadFactoryNames(type, classLoader)
1. 初始化SpringApplication 从spring.factories 读取 listener ApplicationContextInitializer 。 2.运行run方法 3.读取 环境变量 配置信息..... 4. 创建springApplication上下文: ServletWebServerApplicationContext 5. 预初始化上下文 : 读取启动类 6.调用refresh 加载ioc容器 加载所有的自动配置类 创建servlet容器 7.在这个过程中springboot会调用很多监听器对外进行今日头条
-------------------------------2021.7.10-----------------------
掌握自动配置原理和启动流程,就掌握了SpringBoot.
1.springBoot集成其他框架,一般使用@Enablexxx引入@import(类)注解,引入一个类,这个类是实现功能的主要逻辑。
2.import大致有3种用法:
@import(类);
@import(importSelector接口的实现类);
@import(importBeanDefinitionRegistrar接口实现类)
interface DeferredimportSelector extends importSelector 在其他注解解析之后最后解析,例如:SpringBoot默认配置SqlSessionFactory,用户想重新定制一个特定功能的SqlSessionFactory, 就得先加载,默认的通过@Condition注解就不注入到容器中了。从而实现了条件配置。
在application.properties中添加debug=true,能够看到加载了哪些自动配置类。
启动:
ContextLoaderListener启动了SpringApplicationContext
问题1:SpringBoot的jar为什么直接可以运行?
在POM.xml文件中添加了spring-boot-maven-plugin插件,生成的jar就可以直接运行。插件的作用是生成MANIFEST.MF(文件中指定了start-class, );把依赖的jar



