Spring Boot基础
理念:习惯优于配置,内置习惯性配置,无需手动进行配置。使用Spring boot可以很快创建一个独立运行、准生产级别的基于Spring框架的项目,不需要或者只需很少的Spring配置。
特点
- 内置servlet容器,不需要在服务器部署 tomcat。只需要将项目打成 jar 包,使用 java -jar xxx.jar一键式启动项目
- SpringBoot提供了starter,把常用库聚合在一起,简化复杂的环境配置,快速搭建spring应用环境
- 可以快速创建独立运行的spring项目,集成主流框架
- 准生产环境的运行应用监控
Spring Boot核心
基本配置
Spring Boot通常有个Application入口类:
1 | import org.springframework.boot.SpringApplication; |
@SpringBootApplication是Spring Boot的核心注解,它是组合注解,源码如下:
1 |
|
@SpringBootApplication注解组合了@Configuration、@EnableAutoConfiguration和@ComponentScan注解,若不使用@SpringBootApplication注解,则可以在入口类上直接使用@Configuration、@EnableAutoConfiguration和@ComponentScan。
@EnableAutoConfiguration作用是让Spring Boot根据类路径中的jar包依赖为当前项目进行自动配置。例如,添加了spring-boot-starter-web依赖,会自动添加Tomcat和Spring MVC依赖,那么Spring Boot会对Tomcat和Spring MVC进行自动配置。
@Configuration标注在类上,相当于把该类作为spring的xml配置文件中的<beans>
,作用是配置spring容器。
关闭特定的自动配置
使用@SpringBootApplication的exclude参数关闭特定的自动配置。
1 |
Spring Boot的配置文件
Spring Boot使用一个全局的配置文件application.properties或application.yml。这个全局配置文件可以对一些默认配置的配置值进行修改。如修改Tomcat默认的端口号,并将默认的访问路径”/“修改为”/hello”:
1 | server.port=9090 |
starter pom
Spring Boot为我们提供了简化企业级开发绝大多数场景的starter pom,只要使用了应用场景所需要的starter pom,相应的配置就可以消除,就可以得到Spring Boot为我们提供的自动配置的bean。
xml配置
Spring Boot提倡零配置,但实际项目中可能需要使用xml配置,此时可以通过Spring提供的@ImportResource来加载xml配置。
1 |
外部配置
命令行参数配置
Spring Boot是基于jar包运行的,打成jar包的程序可以直接通过下面的命令运行:
1 | java -jar xx.jar |
可以通过以下命令修改端口号:
1 | java -jar xx.jar --server.port=9090 |
常规属性配置
在Spring Boot里,我们只需在application.properties定义属性,直接使用@Value注入即可。
application.properties增加属性:
1 | book.author=tyson |
修改入口类:
1 | import org.springframework.beans.factory.annotation.Value; |
@RestController=@Controller + @ResponseBody,注解的类里面的方法以json格式输出。
类型安全的配置
Spring Boot提供了基于类型安全的配置方式,通过@ConfigurationProperties将配置文件application.properties中配置的属性值映射到当前类的属性中,从而实现类型安全的配置。
类型安全的bean:
1 | import org.springframework.boot.context.properties.ConfigurationProperties; |
通过@ConfigurationProperties加载properties文件内的配置,通过prefix属性指定前缀。
检验代码:
1 | import com.tyson.springbootdemo.config.BookConfig; |
@EnableConfigurationProperties注解将带有@ConfigurationProperties注解的类注入为Spring容器的Bean。
日志配置
Spring Boot 支持 Log4J、Logback、Java Util Logging、Log4J2 作为日志框架,无论使用哪种日志框架,Spring Boot 已为当前使用日志框架的控制台输出及文件输出做好了配置。默认情况下,Spring Boot 使用 Logback 作为日志框架,日志级别为 INFO。
配置日志文件:
1 | logging.path=H:/log/ |
配置日志级别,格式为 logging.level.包名=级别:
1 | logging.level.root=INFO #root级别,项目所有日志 |
配置日志样式:
1 | logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n |
Profile配置
Profile 是 Spring 用来针对不同环境对不同配置提供支持的,全局Profile配置使用 application-{profile}.properties(如application-prod.properties)。通过在 application.properties 中设置spring.profiles.active=prod 来制定活动的Profile。
假如有生产和开发环境,生产环境下端口号为80,开发环境下端口号为8888。配置文件如下:
application-prod.properties:
1 | server.port=80 |
application-dev.properties
1 | server.port=8888 |
application.properties 增加:
1 | spring.profiles.active=prod |
启动程序结果为:
1 | 2019-03-03 09:17:08.003 INFO 17812 --- [ main] c.t.s.SpringbootDemoApplication : The following profiles are active: prod |
Spring Boot的Web开发
spring-boot-starter-web 为我们提供了嵌入的 tomcat 和 Spring MVC 的依赖。
Thymeleaf 模板引擎
JSP 在内嵌的 Servlet 容器上运行会存在一些问题(内嵌 Tomcat、Jetty 不支持以 jar 形式运行 JSP,Undertow 不支持 JSP)。Spring Boot 提供了大量的模板引擎,包含 FreeMarker、Groovy、Thymeleaf、Velocity 和 Mustache,Spring Boot 中推荐使用 Thymeleaf 作为模板引擎,因为 Thymeleaf 提供了完美的 Spring MVC 的支持。
Thymeleaf 基础知识
Thymeleaf 是 Java 类库,它是一个 xml/xhtml/html5 的模板引擎,可以作为 MVC 的 Web 应用的 view 层。Thymeleaf 还提供了额外的模块与 Spring MVC 集成,使用 Thymeleaf 完全可以替代 JSP。
- 引入 Thymeleaf
基本的 Thymeleaf 模板页面,引入了 Bootstrap(作为样式控制)和 jQuery(DOM 操作)。
1 |
|
通过 xmlns:th=”http://www.thymeleaf.org" 命名空间,将静态页面转换为动态视图。需要进行动态处理的元素需使用 “th:” 为前缀。通过 “@{}” 引用 Web 静态资源,这在 JSP 下是极易出错的。
- 访问 model 中的数据
通过 “${}” 访问 model 中的属性,这和 JSP 很相似。需要处理的动态内容需要加上 “th:” 前缀。
1 | <div class="panel panel-primary"> |
- model 中的数据迭代
1 | <div class="panel panel-primary"> |
- 数据判断
通过${not #lists.isEmpty(people)}表达式判断 people 是否为空。Thymeleaf 还支持 >、<、==、!= 等作为比较条件,同时也支持将 SpringEL 表达式语言用于条件中。
1 | <div th:if="${not #lists.isEmpty(people)}"> |
- 在 JavaScript 中访问 model
1 | <script th:inline="javascript"> |
通过 th:inline=”javascript”添加到 script 标签,这样 JavaScript 代码即可访问 model 中的属性;
通过“[[${person}]]”格式可以获得实际的值。
如果需要在 html 代码里访问 model 中的属性,比如我们需要在列表后面单击每一行后面的按钮获得 model 中的值,可做如下处理:
1 | <li class="list-group-item" th:each="person:${people}"> |
与 Spring MVC 集成
在 Spring MVC 中,若我们需要集成一个模板引擎的话,需要定义 ViewResolver,而 ViewResolver 需要定义一个 View。在 Spring MVC 中集成 Thymeleaf 非常简单,Thymeleaf 为我们定义好了 org.thymeleaf.spring4.view .ThymeleafView 和 org.thymeleaf.spring4.view.ThymeleafViewResolver(默认使用 ThymeleafView 作为 View)。Thymeleaf 给我们提供了一个 SpringTemplateEngine 类,用来驱动 Spring MVC 下使用 Thymeleaf 模板引擎,另外提供了一个 TemplateResolver 用来设置通用的模板引擎(包含前缀、后缀等)。
引入依赖:
1 | <!--thymeleaf--> |
xml 配置:
1 | <!--thymeleaf--> |
或者使用 JavaConfig 配置:
1 | import org.springframework.context.annotation.Bean; |
Spring Boot 的 Thymeleaf 支持
Spring Boot 通过 org.springframework.boot.autoconfigure.thymeleaf 包对 Thymeleaf 进行了自动配置,通过ThymeleafAutoConfiguration 类对集成所需的 Bean 进行自动配置,包括 templateResolver、templateEngine 和 thymeleafViewResolvers 的配置。通过 ThymeleafProperties 来设置属性以及默认配置。
1 |
|
实战
- 引入依赖
1 | <dependency> |
引入 Thymeleaf 之后,Controller才能根据逻辑视图名转发到相应的视图。
- JavaBean
1 | public class Person { |
- 页面
1 |
|
页面引入了Bootstrap和jQuery,这些静态文件放置在src/main/resources/static下面。
- Controller
1 | import com.tyson.springbootdemo.pojo.Person; |
Web 相关配置
Spring Boot 提供的自动配置
WebMvcAutoConfiguration 及 WebMvcProperties 定义了 Web 相关的自动配置。
- 自动配置的ViewResolver
1 |
|
- 自动配置的静态资源
将类路径下的/static、/resources、/public 和 /META-INF/resources 文件夹下的静态文件直接映射为/**,可以通过 http://localhost:8080/\*\*访问。
把 webjar 的 /META-INF/resources/webjars/ 下的静态文件映射为/webjar/**,可以通过 http://localhost:8080/webjar/\*\*访问。
- 自动配置的 Formatter 和 Converter
1 | public void addFormatters(FormatterRegistry registry) { |
只要我们定义了 Converter、GenericConverter 和 Formatter 接口的实现类的 Bean,这些 Bean 就会自动注册到 Spring MVC 中。
- 静态首页的支持
把静态首页放到如下目录:
- classpath:/META-INF/resources/index.html
- classpath:/resources/index.html
- classpath:/static/index.html
- classpath:/public/index.html
当我们访问应用根目录 http://localhost:8080/ 时,会直接映射。
实现自己的 MVC 配置
当 Spring Boot 提供的 Spring MVC 不符合要求时,可以通过一个配置类(注解有@Configuration 的类)加上@EnableWebMvc 注解来实现完全自己控制的 MVC 配置。
要想保留 Spring Boot 提供的 MVC 配置,同时增加额外的配置,可以通过定义一个配置类并继承 WebMvcConfigurerAdapter,无需使用@EnableWebMvc注解。
1 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; |
重写的 addViewControllers 方法并不会覆盖 WebMvcAutocConfiguration 中的 addViewControllers(此方法中,Spring Boot 将“/”映射到 index.html),即我们自己的配置和 Spring Boot 的自动配置同时生效。
注册 Servlet、Filter、Listener
当使用嵌入式的 Servlet 容器时,通过将 Servlet、Filter 和 Listener 声明为 Spring Bean 达到注册的效果;或者注册 ServletRegistrationBean、FilterRegistrationBean 和 ServletRegistrationBean 的 Bean。
直接注册 bean:
1 |
|
通过 RegistrationBean 示例:
1 |
|
Tomcat配置
配置 Tomcat
关于 Tomcat 的所有属性都在 org.springframework.boot.autoconfigure.web.ServerPr=8080operties 配置类中做了定义,只需在 application.properties 配置即可。通用的 Servlet 容器配置都以 “server” 作为前缀,而 Tomcat 特有的配置都以 “server.tomcat” 作为前缀。
1 | #配置Servlet容器 |
替换 Tomcat
Spring Boot 默认使用 Tomcat 作为内嵌的 Servlet 容器,如果要使用 Jetty 或者 Undertow 为容器,只需修改 spring-boot-start-web 的依赖即可。
- 替换为 Jetty
在 pom.xml中,将 spring-boot-starter-web 的依赖由 spring-boot-starter-tomcat 替换为 spring-boot-starter-jetty:
1 | <dependency> |
启动 Spring Boot,控制台输出效果如下:
1 | INFO 21724 --- [ main] o.s.b.web.embedded.jetty.JettyWebServer : Jetty started on port(s) 8080 (http/1.1) with context path '/' |
- 替换为 Undertow
将 spring-boot-starter-web 的依赖由 spring-boot-starter-tomcat 替换为 spring-boot-starter-undertow:
1 | <dependency> |
Spring Boot 的数据访问
Docker 常用命令及参数
Docker 镜像命令
(1)Docker 镜像检索
1 | docker search redis |
(2)镜像下载
1 | docker pull redis |
(3)镜像列表
1 | docker images |
(4)删除镜像
删除指定镜像:
1 | docker rmi image-id |
删除所有镜像:
1 | docker rmi ${docker images -q} |
Docker 容器命令
(1)容器基本操作
运行容器,Docker 会为我们生成唯一的标识。
1 | docker run --name container-name -d image-name |
(2)容器列表
查看运行中的容器列表:
1 | docker ps |
查看运行和停止状态的容器:
1 | docker ps -a |
(3)停止和启动容器
停止容器:
1 | docker stop container-name/container-id |
启动容器:
1 | docker start container-name/container-id |
端口映射:Docker 容器中运行的软件所使用的端口,在本机和本机的局域网是不能访问的,需要将 Docker 容器的端口映射到当前主机的端口上,这样我们在本机和本机的局域网才能访问该软件。
映射容器的6379端口到虚拟机的6378端口上:
1 | docker run -d -p 6378:6379 --name port-redis resdis |
删除单个容器:
1 | docker rm container-id |
删除所有容器:
1 | docker rm ${docker ps -a -q} |
查看容器日志:
1 | docker logs container-name/container-id |
登录容器:
1 | docker exec -it container-id/container-name bash |
登录后可以在容器中进行常规的 Linux 系统操作命令。
Spring Boot 对 Spring Data JPA 的支持
JPA 是一个基于 O/R 映射的标准规范(不提供实现)。Spring Data JPA 是 Spring Data 的一个子项目,它通过提供基于 JPA 的Repository 极大地减少了 JPA 作为数据访问方案的代码量。
JDBC 的自动配置
spring-boot-starter-data-jpa 依赖于 spring-boot-starter-jdbc,Spring Boot 对 JDBC 做了一些自动配置,源码在 org.springframework.boot.autoconfigure.jdbc 下。
在 DataSourceAutoConfiguration 类中配置了对 DataSource 的自动配置,通过”spring.datasource”为前缀的属性自动配置 dataSource;Spring Boot 开启了注解事务的支持(@EnableTransactionManagement);还配置了一个jdbcTemplate。以下是 JdbcProperties 类的源码:
1 |
|
对 JPA 的自动配置
Spring Boot 对 JPA 的自动配置放置在 org.springframework.boot.autoconfiguration.orm.jpa 下,从HibernateJpaAutoConfiguration 可以看出,Spring Boot 默认的 JPA 实现是Hibernate。
配置 JPA 可以在 application.properties 中使用 spring.jpa 为前缀的属性来配置。
以下是 JpaProperties 类的源码:
1 |
|
在 JpaBaseConfiguration 类中,Spring Boot 为我们创建了 transactionManager、jpaVendorAdapter、entityManagerFactory 等 bean。JpaBaseConfiguration 还有 getPackagesToScan 方法,可以自动扫描有@Entity 注解的实体类。
对 Spring Data JPA 的自动配置
Spring Boot 对 Spring Data JPA 的自动配置放置在 org.springframework.boot.autoconfigure.data.jpa 中。JpaRepositoriesAutoConfiguration 是依赖于 HibernateJpaAutoConfiguration 配置的,且 Spring Boot 自动开启了对 Spring Data JPA 的支持,无需在配置类显式声明@EnableJpaRepositories。
在 Spring Boot 下使用 Spring Data JPA,首先在项目的 maven 依赖里添加 spring-boot-starter-data-jpa,然后只需定义DataSource、实体类和数据访问层,在需要使用数据访问的地方注入数据访问层的 Bean 即可。
@Value原理
@Value的解析就是在bean初始化阶段。BeanPostProcessor定义了bean初始化前后用户可以对bean进行操作的接口方法,它的一个重要实现类AutowiredAnnotationBeanPostProcessor为bean中的@Autowired和@Value注解的注入功能提供支持。
启动过程
准备Environment——发布事件——创建上下文、bean——刷新上下文——结束。
构造SpringApplication的时候会进行初始化的工作,初始化的时候会做以下几件事:
判断运行环境类型,有三种运行环境:NONE 非 web 的运行环境、SERVLET 普通 web 的运行环境、REACTIVE 响应式 web 的运行环境
加载 spring.factories 配置文件, 并设置 ApplicationContextInitializer
加载配置文件, 设置 ApplicationListener
SpringApplication构造完成之后调用run方法,启动SpringApplication,run方法执行的时候会做以下几件事:
构造一个StopWatch,观察SpringApplication的执行
找出SpringApplicationRunListener,用于监听SpringApplication run方法的执行。监听的过程中会封装SpringApplicationEvent事件,然后使用ApplicationEventMulticaster广播出去,应用程序监听器ApplicationListener会监听到这些事件
发布starting事件
加载配置资源到environment,包括命令行参数、application.yml等
发布environmentPrepared事件
创建并初始化ApplicationContext,设置environment,加载配置
refresh ApplicationContext
- 设置beanFactory
- 调用BeanFactoryPostProcessors
- 初始化消息源
- 初始化事件广播器(initApplicationEventMulticaster)
- 调用onRefresh()方法,默认是空实现
- 注册监听器
- 实例化non-lazy-init单例
- 完成refresh
- 发布ContextRefreshedEvent事件
发布started事件,启动结束
阅读量