一、简介
Spring Boot简化了Spring应用的开发,采用约定大于配置的思想,去繁从简,很方便就能构建一个独立的、产品级别的应用。
1.传统J2EE开发的缺点
开发笨重、配置繁多复杂、开发效率低下、部署流程复杂、第三方技术集成难度大。
2.SpringBoot的优点
- 快速重建独立运行的Spring项目以及与主流框架集成。
- 使用嵌入式的Servlet容器,应用无需打成WAR包
- starters自动依赖与版本控制
- 大量的自动配置、简化开发,也可以修改其默认值
- 无需配置XML,无代码生成
- 准生产环境的运行时应用监控
- 与云计算的天然继承
3.SpringBoot helloworld说明
1.starters
- SpringBoot为我们提供了简化企业级开发绝大多数场景的starters pom(启动器),只要引入了相应场景的starters pom,相关技术的绝大部分配置将会消除(字段配置),从而简化我们的开发。业务中我们就会使用到SpringBoot为我们字段配置的Bean。
- 这些starters几乎涵盖了javaee所有常用场景,SpringBoot对这些场景依赖的jar也做了严格的测试和版本控制。
- spring-boot-dependencies里面定义了jar包的版本。
2.入口类和@SpringBootApplication
- 程序从main方法开始运行。
- 使用SpringApplication.run()加载主程序类
- 主程序类需标注@SpringBootApplication
- @EnableAutoConfiguration是核心注解
- @Import导入所有的自动配置场景
- @AutoConfigurationPackage定义默认的包扫描规则。
- 程序启动扫描主程序类所在的包以及下面所有子包的组件
3.自动配置
自动配置xxxAutoConfiguration
- SpringBoot中存现大量的这些类,这些类的作用就是帮我们进行自动装配
- 它会将这个场景需要的所有组件都注册到容器中,并配置好
- 他们在类路径下的META-INF/spring.factories文件中
- spring-boot-autoconfigure.jar中包含了所有场景的字段配置类代码
- 这些自动配置类是SpringBoot进行自动装配的关键。
二、SpringBoot配置
1.配置文件
-
SpringBoot使用一个全局的配置文件。配置文件名是固定的。
-application.properties或者application.yml -
配置文件放在src/main/resources目录或者类路径/config下。
-
全局配置文件的作用是对一些默认配置进行修改
2.配置文件值注入
- @Value和@ConfigurationProperties为属性注入值进行对比
对比点 | @ConfigurationProperties | @Value |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
-
属性名匹配规则
-person.firstName 使用标准方式
-person.first-name 使用-
-person.first_name 使用_
-PERSON_FIRST_NAME 推荐系统属性使用这种写法 -
@PropertySource
加载指定的配置文件 -
ConfigurationProperties
-与@Bean结合为属性赋值
-与@PropertySource(只能用于properties文件)结合读取指定文件。 -
ConfigurationProperties Validation
-支持JSR303进行配置文件值校验。
@Component
@PropertySource(value={
"classpath:person.properties"})
@ConfigurationProperties(prefix="person")
@Validated
public class Person{
@Email
@Value("${person.email}")
private String email;
}
- ImportResource读取外部配置文件
3.配置文件占位符
-
RandomValuePropertySource
配置文件中可以使用随机数
-${random.value}
-${random.int}
-${random.long}
-${random.int(10)}
-${random.int[1024,65536]} -
属性配置占用符
-可以在配置文件中引用前面配置过的属性(Y优先级前面配置过的这里都可以使用)。
-${ app.name:默认值}来指定找不到属性时的默认值。
app.name=MyApp
app.description=${app.name} is a SpringBoot Application
4.profile
profile是Spring对不同环境提供不同配置功能的支持,可以通过激活指定参数的方式快速切换环境。
1.多profile文件形式
- 格式:application-{profile}.properties/yml
application-dev.properties、application-prod.properties
2.多profile文档块模式
spring.profiles.active=prod #激活指定配置
spring.profiles=prod
server.port=80
# default表示未指定时的默认配置
spring.profiles=default
server.port=8080
3.激活方式
- 命令行:–spring.profiles.active=dev
- 配置文件:spring.profiles.active=dev
- jvm参数:-Dspring.profiles.active=dev
5.配置文件加载位置
SpringBoot启动会扫描一下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件。
- file:./config/
- file:./
- classpath:/config/
-classpath:/
-以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。
-可以通过配置spring.config.location来改变默认配置。
6.外部配置加载顺序
- 命令行参数
- 来自java:comp/env的JNDI属性
- Java系统属性(System.getProperties())
- 操作系统环境变量
- RandomValuePropertySource配置的random.*属性值
- jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
- jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
- jar包外部的application.properties或application.yml(不带spring.profile)配置文件
- jar包内部的application.properties或application.yml(不带spring.profile)配置文件
- @Configuration注解类上的@PropertySource。
- 通过SpringApplication.setDefaultproperties指定的默认属性。
7.自动配置原理
1.SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration
2.@EnableAutoConfiguration作用
- 利用EnableAutoConfigurationImportSelector给容器中导入一些组件。
- 将类路径小META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加入到了容器中。
3.@Conditional派生注解
@Conditional扩展注解 | 作用(判断是否满足当期指定条件) |
---|---|
@ConditionalOnJava | 系统的java版本是否符合要求 |
@ConditionalOnBean | 容器中存在指定Bean |
@ConditionalOnMissingBean | 容器中不存在指定Bean |
@ConditionalOnExpression | 满足SpEL表达式指定 |
@ConditionalOnClass | 系统中有指定的类 |
@ConditionalOnMissingClass | 容器中没有指定类 |
@ConditionalOnSingleCandidate | 容器中只有一个指定的Bean,或者这个Bean是首选Bean |
@ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
@ConditionalOnResource | 类路径下是否存在指定资源文件 |
@ConditionalOnWebApplication | 当前是web环境 |
@ConditionalOnNotWebApplication | 当前不是web环境 |
@ConditionalOnJndi | JNDI存在指定项 |
- 作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效。
三、SpringBoot与日志
1.日志框架
市场上存在非常多的日志框架,JUL(java.util.logging)、JCL(Apache Commons Logging)、Log4J、Log4J2、Logback、SLF4j、jboss-logging等。
- SpringBoot早框架内部使用JCL。spring-boot-starter-logging采用了slf4j+logback的形式,SpringBoot也能自动配置(jul、log4j2、logback)并简化配置。
日志门面 | 日志实现 |
---|---|
JCL、SLF4J、jboss-logging | log4j、JUL、Log4j2、Logback |
日志系统 | 配置文件 |
---|---|
Logback | logback-spring.xml、logback-spring.groovy、logback.xml或logback.groovy |
Log4j2 | log4j2-spring.xml、log4j2.xml |
JUL | logging.properties |
- 总结:
1.SpringBoot底层也是使用slf4j+logback的方式进行日志记录。
2.SpringBoot也把其他的日志都替换成了slf4j。
3.如果要引入其他日志框架,要排除Spring框架的commons-logging依赖。
四、Web开发
1.SpringBoot对静态资源的映射规则
- 所有/webjars/**,都去classpath:/META-INF/resources/webjars/ 下面找资源。
- “/**” 访问当前项目的任何资源,都去(静态资源的文件夹)找映射。
- 欢迎页;静态资源文件夹下的所有index.html页面,被"/**" 映射。
- 所有的 **/favicon.ico都是在静态资源文件下找。
2.SpringMVC自动配置
1.SpringMVC auto-configuration
SpringBoot对SpringMVC的默认配置(WebMvcAutoConfiguration)如下:
-
包含了ContentNegotiatingViewResolver和BeanNameViewResolver。
- 自动配置了ViewResolver
- ContentNegotiatingViewResolver:组合所有的视图解析器
-
支持静态资源,包括支持Wenjars
-
静态首页访问
-
支持favicon.ico
-
自动注册了Converter、GenericConverter、Formatter。
- Converter:转换器。
- Formatter:格式化器
-
支持HttpMessageConverters
- HttpMessageConverter:SpringMVC用来转换Http请求和响应。
- HttpMessageConverters:从容器中确定,获取所有的HttpMessageConverter;
-
自动注入MessageCodesResolver,定义错误码生成规则。
-
自动使用ConfigurableWebBindingInitializer。
2.扩展SpringMVC
编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型,不能标注@EnableWebMvc注解
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/desperado").setViewName("success");
}
}
原理
- WebMvcAutoConfiguration是SpringMVC的自动配置类。
- 在做其他自动配置时会导入。
- 容器中所有的WebMvcConfigurer都会一起被注册。
- 我们自定义的配置类也会被调用。
3.全面接管SpringMVC
如果想要使SpringMVC的自动配置失效,只需要在我们自定义的配置类中添加@EnableWebMvc注解即可。
@EnableWebMvc
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/desperado").setViewName("success");
}
}
原理
- @EnableWebMvc的注解
@Import(DelegatingWebMvcConfiguation.class)
public @interface EnableWebMvc{
}
- DelegatingWebMvcConfiguation
@Configuration
public class DelegatingWebMvcConfiguation extend WebMvcConfigurationSupport{
}
- WebMvcAutoConfiguration
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({
Servlet.class,DispatcherServlet.class,
WebMvcConfigurerAdapter.class})
//容器中没有这个组件,这个自动配置类才会生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({
DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration{
}
- @EnableWebMvc会将WebMvcConfigurationSupport组件导入进来。
- 导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能。
4.修改默认配置
- SpringBoot在自动配置很多组件的时候,显卡容器中有没有用户自己配置的(@Bean 、@Component),如果有就用用户配置的,如果没有,才会进行自动配置;如果某些组件可以有多个,将用户配置的和自己默认的组合起来。
- 在SpringBoot中有许多的xxxConfigurer帮助我们进行扩展配置
- 在SpringBoot中有许多的xxxCustomizer帮助我们进行定制配置
5.默认访问首页
使用自定义WebMvcConfigurationAdapter进行配置
//使用WebMvcConfigurationAdapter可以扩展SpringMVC的功能
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送/desperado 请求来到success
registry.addViewController("/desperado").setViewName("success");
}
//所有的webMvcConfigurerAdapter组件都会一起起作用
@Bean //将组件注册到容器
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//配置默认路径的页面
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
}
};
return adapter;
}
}
6.国际化
1.编写国际化配置文件
编写不同语言的配置文件,比如login.properties、login_en_US.properties、login_zh_CN.properties等。
2. SpringBoot自动配置好了管理国际化资源文件的组件。
@EnableConfigurationProperties
public class MessageSourceAutoConfiguration {
private static final Resource[] NO_RESOURCES = new Resource[0];
public MessageSourceAutoConfiguration() {
}
@Bean
@ConfigurationProperties(
prefix = "spring.messages"
)
public MessageSourceProperties messageSourceProperties() {
return new MessageSourceProperties();
}
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
if (StringUtils.hasText(properties.getBasename())) {
//设置国际化资源文件的基础名(去掉语言国家代码)
messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));
}
if (properties.getEncoding() != null) {
messageSource.setDefaultEncoding(properties.getEncoding().name());
}
messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
Duration cacheDuration = properties.getCacheDuration();
if (cacheDuration != null) {
messageSource.setCacheMillis(cacheDuration.toMillis());
}
messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
return messageSource;
}
原理
根据请求头带来的区域信息获取Locale进行国际化。
五、错误处理机制
1.默认的错误处理机制
- 浏览器,默认返回一个默认的错误页面。
- 其他客户端,默认响应一个json数据。
原理
- 在DefaultErrorAttributes中获取错误页面的信息
public class DefaultErrorAttributes implements ErrorAttributes {
//获取错误页面的信息
public Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
Map<String, Object> errorAttributes = new