文章目录
Spring Boot概述
Spring Boot是个啥
与其说Spring Boot是一个框架,不如说它是一个工具,Spring Boot不仅继承了Spring框架原有的优秀特性,还简化了配置来方便用户完成Spring应用的整个搭建和开发过程。
其次Spring Boot里集成了大量的框架解决了依赖包的版本冲突,以及引用的稳定性的问题
为啥用SpringBoot
因为SpringBoot的优秀特性
(1)SpringBoot内置了一些servlet容器,如tomcat、jetty、undertow
(2)易部署:可以创建独立的Spring应用程序,并且在基于Maven或Gradle插件下,可以创建可执行的jar包或war包
(3)可以通过yml(一种标记语言)对SpringBoot进行简单配置,如更改端口号等,yml文件提高了网络传输和解析的速度
(4)集成了很多starter,这些starter会把需要用的其他功能组件囊括进来,放入自己项目的pom文件中,也就无需自己进行手动添加非常多的依赖
关于starter的命名:如果是springboot自己的stater,命名规则为spring-boot-starter-*,如果是第三方的starter,则命名规则是*-starter
入门案例
所有程序的入门案例当然是逃不开hello world的,这是一个程序员的自我修养
核心步骤(这里采用子模块的方式建立工程)
- 创建一个父级maven工程,在pom文件添加starter
- 创建一个子级maven工程,在pom文件中添加创建springBoot web工程的依赖(附加,可以添加Spring boot工程打包的依赖)
- 编写springBoot的启动类
- 编写yml文件,对springBoot进行简单的配置
具体实现
文件结构
-
创建一个父级maven工程,在pom文件添加starter
-
创建一个子级maven工程,在pom文件中添加创建springBoot web工程的依赖
-
编写springBoot的启动类
package com.dean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
//@EnableAutoConfiguration 指定该类是启动类
//@SpringBootApplication内置了@EnableAutoConfiguration
//该注释会将该类所在的包作为整个工程的父包 spring会自动扫描父包下的所有子包
@SpringBootApplication
public class InitApplication {
@RequestMapping("/")
public String hello()
{
return "hello world";
}
public static void main(String[] args) {
//指定InitApplication为根工程
SpringApplication.run(InitApplication.class,args);
}
}
- 编写yml文件,对springBoot进行简单的配置
server:
port: 8090 # 修改端口号
servlet:
context-path: /hello # 修改默认访问路径
SpringBoot的日志管理
以下内容来自百度
SpringBoot 内部使用Commons Logging来记录日志,但同时也保留了外部接口可以让一些日志框架来进行实现,默认情况下Spring Boot使用Logback作为日志的实现框架
核心步骤(简单使用 & 自定义方式)
- pom.xml中添加依赖
- 创建SpringBoot启动类
- 创建前端控制器UserController
- 简单配置 在yml文件中进行配置
- 自定义日志 编写xml文件
具体实现
-
pom.xml中添加依赖
-
创建SpringBoot启动类
-
创建前端控制器UserController
-
简单配置 在yml文件中进行配置
如果希望简单的配置一下,只需要在SpringBoot的核心配置文件处理即可
# 开启debug模式 配置springboot的日志管理
debug: true
# 将日志输出到文件 (yml文件中对日志的配置和logback不能同时存在)
logging:
# file 指定日志存储的文件
file: E:\\ER Doc\\Frame_Class\\log\\spring.boot.log
level:
# root 打印所有日志
root: info
- 自定义日志 编写xml文件
如果需要复杂一些,进行一些日志的自定义设置,可以使用logback
<?xml version="1.0" encoding="UTF-8"?>
<!--6、logback的配置文件-->
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="E:\\ER Doc\\Frame_Class\\log" />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小 超过该大小会自动滚动-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- show parameters for hibernate sql 专为 Hibernate 定制 借助Hibernate框架将日志信息保存到数据库-->
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
<!--myibatis log configure 借助MyBatis框架将日志信息保存到数据库-->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
<!--日志异步到数据库 -->
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
<!--日志异步到数据库 -->
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<!--连接池 -->
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
<user>root</user>
<password>root</password>
</dataSource>
</connectionSource>
</appender>
</configuration>
自定义属性的获取
主要有三种方式:@Value、环境变量Environment以及自定义的类
yml文件中自定义的属性
com:
jdbc:
driver: com.dean.driver.Driver
url: http://localhost::8090
username: root
pwd: 123456
list:
- html
- oracle
- mybatis
- mysql
- controller层通过@Value获取
@RestController
@RequestMapping("/user")
public class UserController {
//方式1: 通过@Value获取yml文件中的参数
@Value("${com.jdbc.driver}")
private String driver;
@GetMapping("/login")
public String login()
{
System.out.println(driver);
return "hello ";
}
}
- controller层通过环境变量获取
@RestController
@RequestMapping("/user")
public class UserController {
//方式2: 通过Spring提供的环境变量
@Resource
private Environment env;
@GetMapping("/login")
public String login()
{
System.out.println(env.getProperty("com.jdbc.url"));
return "hello ";
}
}
- controller层通过新建类获取
新建一个类并添加注释@ConfigurationProperties+@Component
进行获取
DataSourceProperties类
@Component
@ConfigurationProperties(prefix = "com.jdbc") //前缀与yml文件中的前缀一致
public class DataSourceProperties {
//变量名需完全与yml文件中的名称一致
private String driver;
private String url;
private String username;
private String password;
//集合数据
private List<String> list;
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}
Controller层获取属性值
@RestController
@RequestMapping("/user")
public class UserController {
//方式3: 通过类的setter/getter方法
@Resource
private DataSourceProperties datas;
@GetMapping("/login")
public String login()
{
System.out.println(datas.getUsername());
System.out.println(datas.getList());
return "hello ";
}
}
Thymeleaf
关于Thymeleaf的吸引力
简单来说,Thymeleaf是一个模板引擎,它可以完全代替jsp,相对于其他的模板引擎,它主要有以下的吸引力:
(1)Thymeleaf在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。
原因是:Thymeleaf支持html原型,然后在html的标签中增加额外的属性来达到模板+数据的展示方式。浏览器解释html时会忽略未定义的标签属性,所以可以静态运行,当有数据返回到页面时,Thymeleaf标签会动态地替换掉静态内容,使页面动态显示。
(2)Thymeleaf开箱即用,Thymeleaf提供了标准和Spring标准两种语言,可以直接套用模板实现JSTL、OGNL表达式效果,避免频繁套用模板,改jstl,改标签地困扰。同时开发人员可以扩展和创建自定义地语言。
(3)Thymeleaf提供了spring标准语言和一个SpringMvc完美集成的可选模块,可以快速的实现表单绑定,属性编辑器,国际化等功能
核心步骤
- pom.xml中添加所需依赖
- 编写启动类
- 编写SpringBoot核心文件
- 编写前端页面
- 编写SpringMVC的核心类,配置主页
- 编写前端控制器
- 练习Thymeleaf语法
具体实现
-
整体文件结构
-
pom.xml中添加所需依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
- 编写启动类
@SpringBootApplication
public class InitApplication {
public static void main(String[] args) {
SpringApplication.run(InitApplication.class,args);
}
}
- 编写SpringBoot核心文件
在核心文件里配置了视图解析器
spring:
# 配置视图解析器
thymeleaf:
# 视图路径前缀
prefix: classpath:/templates/views/
# 视图路径后缀
suffix: .html
- 编写前端页面
首页
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<a href="/user/main">Test</a>
</body>
</html>
主页
<!DOCTYPE html>
<!--将标签替换为thymeleaf的头部声明 使用thymeleaf语法-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>主页</h1>
</body>
</html>
- 编写SpringMVC的核心类,配置主页
@Configuration
public class WebConfig implements WebMvcConfigurer {
//配置首页
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
}
- 编写前端控制器
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/main")
public String test(Model model) throws Exception
{
System.out.println("Controller is test");
model.addAttribute("message","hello world");
User user=new User("1","zz",18,new Date());
model.addAttribute("user",user);
model.addAttribute("count",100);
List<User> users=new ArrayList<>();
users.add(user);
users.add(new User("2","xy",23,new Date()));
users.add(new User("3","yx",26,new Date()));
users.add(new User("4","ld",28,new Date()));
model.addAttribute("users",users);
return "main";
}
}
练习Thymeleaf语法
<!DOCTYPE html>
<!--将标签替换为thymeleaf的头部声明 使用thymeleaf语法-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h1>主页</h1>
<!--(1)获取controller层设定的参数-->
<h2 th:text="${message}"></h2>
<h2 th:text="*{message}"></h2>
<!--(2) controller层参数成为行内值-->
<h2 th:inline="text">message: [[${message}]]</h2>
<!--(3) 当参数为对象时,获取对象的属性值-->
<div th:object="${user}">
<p th:inline="text">id:[[${user.id}]]</p>
<p th:inline="text">name:[[${user.name}]]</p>
<p th:inline="text">age:[[${user.age}]]</p>
<p th:inline="text">birth:[[${user.birth}]]</p>
</div>
<!--(4) 脚本内联-->
<script th:inline="javascript">
let count=[[${count}]]
if(count === 100)
{
alert("ok")
}
else {
alert("fail")
}
</script>
<!--(5) 链式表达式,用于标签的引用-->
<!--链接会被解析为/user/main?id=100-->
<a th:href="@{/user/main(id=${count})}">Test link</a>
<!--(6) 遍历-->
<div th:each="its,iterStat:${users}"> <!--its,iterStat:是固定写法-->
<p th:inline="text">id:[[${its.id}]] 姓名:[[${its.name}]] 年龄:[[${its.age}]] 生日:[[${its.birth}]]</p>
</div>
<!--(7)th布局 推荐使用绝对路径 会自动进行视图解析-->
<div class="box" th:include="/box/footer::footer"></div> <!--会在浏览器端显示class名称-->
<div class="box" th:replace="/box/footer::footer"></div> <!--不在浏览器端显示class名称-->
</body>
</html>