前言
学习基础
spring框架基础(Spring IOC、Spring AOP、Spring MVC…)
Maven基础
学习内容
- Spring Boot特点
- Spring Boot常用注解
- Spring Boot自动装配
- Spring Boot核心配置文件
- Spring Boot项目搭建流程
- Spring Boot集成
- Spring Boot应用部署
- Spring Boot Stater制作
学习目标
熟练使用SpringBoot开发应用、集成、查找定位问题
Spring Boot 概述
简介
SpringBoot是由Pivotal团队在2013年开始研发、2014年4月发布第一个版本的全新开源的轻量级框架。 它基于Spring4.0设计,主要是简化了使用 Spring 的难度。 不仅继承了Spring框架原有的优秀特性,而且还通过简化配置、提供各种启动器来进一步简化了Spring应用的整个搭建和开发过程。
简化Spring应用开发的一个框架;整个Spring技术栈的一个大整合;J2EE开发的一站式解决方案;
特点
优点
- 简化Spring配置,快速构建项目,适合微服务开发
- 提供主流框架依赖,对主流开发框架的无配置集成
- 支持运行期内嵌容器,如 Tomcat、Jetty
- 提供运行时的应用监控极大地提高了开发、部署效率
缺点
- 集成度较高,使用过程中不太容易了解底层,入门容易精通难
- 由于内部封装比较深,部分错误调试难度比一般Spring应用程序要大很多
Spring Boot 快速入门
1. 新建项目
2. 添加依赖
3. 添加配置
4. 添加主启动类
5. 添加Controller类
6. 运行
7. 打包部署
SpringBoot 基础
SpringBoot启动类
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
@SpringBootApplication
标注在某个类上说明这个类是SpringBoot应用的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用。@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 {
...
}
@SpringBootConfiguration 标注在某个类上,表示这是一个Spring Boot的配置类。@Configuration-配置类上来标注这个注解;配置类;配置文件;配置类也是容器中的一个组件;@Component-Spring组件类上来标注这个注解 @EnableAutoConfiguration 开启自动配置功能,这样SpringBoot自动配置才能生效
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
@AutoConfigurationPackage-自动配置包 @Import(AutoConfigurationPackages.Registrar.class) @Import是Spring底层注解,作用是给容器中导入一个组件;导入的组件由AutoConfigurationPackages.Registrar.class将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件进行扫描并注册到Spring容器 @Import(EnableAutoConfigurationImportSelector.class)- 导入组件选择器,就是给容器中导入这个场景需要的所有组件,并配置好这些组件。将所有需要导入的组件以全类名的方式返回,将组件添加到容器中,容器中导入非常多的自动配置类(xxxAutoConfiguration)。免去了我们手动编写配置注入功能组件等的工作。
Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作
Spring Boot配置
全局配置文件
SpringBoot使用一个固定名称的全局配置文件(application.properties/application.yml)。可以通过配置文件来修改SpringBoot自动配置的默认值。
spring:
port: 8100
servlet:
context-path: /jclab
默认配置:https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/html/appendix-application-properties.html#common-application-properties
yaml基础
多配置文件及自定义配置文件
在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml
默认使用application.properties的配置;
激活指定指定的profile
- 在配置文件中指定
spring.profiles.active=dev
- 命令行:
java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar —spring.profiles.active=dev;
可以直接在测试的时候,配置传入命令行参数
- 虚拟机参数;
配置文件加载位置及加载顺序
springboot启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
- file:./config/
- file:./
- classpath:/config/
- classpath:/
SpringBoot会从这四个位置全部加载主配置文件,优先级由高到底,高优先级的配置会覆盖低优先级的配置,互补配置(可以通过spring.config.location来改变默认的配置文件位置)
外部配置 SpringBoot也可以从以下位置加载配置, 优先级从高到低,高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置
- 命令行参数
- 来自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指定的默认属性**
配置文件值的注入方式
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
@ConfigurationProperties(JavaBean方式)
@Component
@PropertySource(value = {"classpath:person.properties"})
@ConfigurationProperties(prefix = "person") // 默认从全局配置文件中获取值,修改为person.properties
@Validated //注入值数据校验
public class Person {
/**
* <bean class="Person">
* <property name="lastName" value="字面量/${key}从环境变量、配置文件中获取值/#{SpEL}"></property>
* <bean/>
*/
//lastName必须是邮箱格式
@Email
//@Value("${person.last-name}")
private String lastName;
//@Value("#{11*2}")
private Integer age;
//@Value("true")
private Boolean boss;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
// getter setter
...
}
@ImportResource - 导入Spring的配置文件,让配置文件里面的内容生效,Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;想让Spring的配置文件生效,加载进来,@ImportResource标注在一个配置类上
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloService" class="com.jclab.springboot.service.HelloService"></bean>
</beans>
@ImportResource(locations = {"classpath:beans.xml"})
SpringBoot推荐给容器中添加组件的方式-推荐使用全注解的方式
/**
* @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件
* 在配置文件中用<bean><bean/>标签添加组件
*/
@Configuration
public class MyAppConfig {
//将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
@Bean
public HelloService helloService02(){
System.out.println("配置类@Bean给容器中添加组件了...");
return new HelloService();
}
}
自动配置原理
@SpringBootApplication
—> @EnableAutoConfiguration
—> 利用EnableAutoConfigurationImportSelector给容器中导入一些组件
将类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中,每一个这样的 xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中,用他们来做自动配置
—> 以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理
@Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
@EnableConfigurationProperties(HttpEncodingProperties.class) //启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中
@ConditionalOnWebApplication //Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnClass(CharacterEncodingFilter.class) //判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) //判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
public class HttpEncodingAutoConfiguration {
//他已经和SpringBoot的配置文件映射了
private final HttpEncodingProperties properties;
//只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
this.properties = properties;
}
@Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取
@ConditionalOnMissingBean(CharacterEncodingFilter.class) //判断容器没有这个组件?
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}
根据当前不同的条件判断,决定这个配置类是否生效;一但这个配置类生效,这个配置类就会给容器中添加各种组件;这些组件的属性是从指定的配置类(对应的properties类)中获取的,这些类里面的每一个属性又是和配置文件绑定的 Conditional派生注解:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效
可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;
Spring Boot日志框架
SpringBoot底层是使用slf4j+logback的方式进行日志记录,把其他的日志都替换成了slf4j(引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可)
切换日志框架
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
修改日志的默认配置
properties
logging.level.com.atguigu=trace
#logging.path=
# 不指定路径在当前项目下生成springboot.log日志
# 可以指定完整的路径;
#logging.file=G:/springboot.log
# 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
logging.path=/spring/log
# 在控制台输出的日志的格式
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
# 指定文件中日志输出的格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
xml
SpringBoot Web开发
静态资源的映射规则
WebMvcAutoConfiguration:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Integer cachePeriod = this.resourceProperties.getCachePeriod();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(
registry.addResourceHandler("/webjars/**")
.addResourceLocations(
"classpath:/META-INF/resources/webjars/")
.setCachePeriod(cachePeriod));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
//静态资源文件夹映射
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(
this.resourceProperties.getStaticLocations())
.setCachePeriod(cachePeriod));
}
}
//配置欢迎页映射
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(
ResourceProperties resourceProperties) {
return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
//配置喜欢的图标
@Configuration
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
public static class FaviconConfiguration {
private final ResourceProperties resourceProperties;
public FaviconConfiguration(ResourceProperties resourceProperties) {
this.resourceProperties = resourceProperties;
}
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
//所有 **/favicon.ico
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
faviconRequestHandler()));
return mapping;
}
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
requestHandler
.setLocations(this.resourceProperties.getFaviconLocations());
return requestHandler;
}
}
Spring MVC配置
1、SpringMVC默认配置
Spring Boot 自动配置好了SpringMVC
以下是SpringBoot对SpringMVC的默认配置:(WebMvcAutoConfiguration)
- Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans.- 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发?重定向?))
- ContentNegotiatingViewResolver:组合所有的视图解析器的;
- 如何定制:我们可以自己给容器中添加一个视图解析器;自动的将其组合进来;
- 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发?重定向?))
- Support for serving static resources, including support for WebJars (see below).静态资源文件夹路径,webjars
- Static
index.html
support. 静态首页访问 - Custom
Favicon
support (see below). favicon.ico 自动注册了 of
Converter
,GenericConverter
,Formatter
beans.- Converter:转换器; public String hello(User user):类型转换使用Converter
Formatter
格式化器; 2017.12.17===Date;@Bean<br /> @ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")//在文件中配置日期格式化的规则<br /> public Formatter<Date> dateFormatter() {<br /> return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件<br /> }<br /> 自己添加的格式化器转换器,我们只需要放在容器中即可
- Converter:转换器; public String hello(User user):类型转换使用Converter
Support for
HttpMessageConverters
(see below).- HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User—-Json;
HttpMessageConverters
是从容器中确定;获取所有的HttpMessageConverter;
自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中(@Bean,@Component)
- HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User—-Json;
- Automatic registration of
MessageCodesResolver
(see below).定义错误代码生成规则 - Automatic use of a
ConfigurableWebBindingInitializer
bean (see below).
我们可以配置一个ConfigurableWebBindingInitializer来替换默认的;(添加到容器)
初始化WebDataBinder;
请求数据=====JavaBean;
org.springframework.boot.autoconfigure.web:web的所有自动场景;
If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration
class of type WebMvcConfigurerAdapter
, but without @EnableWebMvc
. If you wish to provide custom instances of RequestMappingHandlerMapping
, RequestMappingHandlerAdapter
or ExceptionHandlerExceptionResolver
you can declare a WebMvcRegistrationsAdapter
instance providing such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration
annotated with @EnableWebMvc
.
2、扩展SpringMVC
<mvc:view-controller path="/hello" view-name="success"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean></bean>
</mvc:interceptor>
</mvc:interceptors>
3、全面接管SpringMVC
需要在配置类中添加@EnableWebMvc即可
//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
@EnableWebMvc
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
//浏览器发送 /jcoo 请求来到 success
registry.addViewController("/jcoo").setViewName("success");
}
}
RESTful
国际化
统一异常处理
Spring Boot数据访问
JDBC
整合Druid
整合Mybatis
整合Spring Data JPA
Spring Boot整合案例
Redis
RabbitMQ
参考
https://docs.spring.io/spring-boot/docs/
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples