1. Введение в SpringBoot
1. Что такое Spring Boot
Справочная информация: разработка Spring громоздка, существует много файлов конфигурации, сложный процесс развертывания и сложно интегрировать сторонние фреймворки. Это снижает эффективность разработки
SpringBoot — это фреймворк, упрощающий создание и разработку приложений Spring.
Интегрирует весь стек технологий Spring и является универсальным решением для разработки JavaEE.
2. Зачем использовать SpringBoot
преимущество:
- Может быстро создавать проекты Spring и интегрироваться с основными платформами.
- Встроенный контейнер сервлетов, нет необходимости вручную развертывать военный пакет
- Используйте стартер для управления зависимостями и контроля версий
- Множество автоматических настроек для упрощения разработки
- Обеспечивает мониторинг во время выполнения для готовых к производству сред.
- XML-файл не требуется
Во-вторых, первая программа SpringBoot
1. Шаги работы
шаг:
1.1 Создайте проект jar Maven
Традиционные приложения должны создать веб-проект, затем упаковать приложение в военный пакет, а затем развернуть его в контейнере.
И SpringBoot нужно только ввести в пакет jar, в котором есть встроенный tomcat
1.2 Импорт зависимостей, связанных с SpringBoot
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ly</groupId>
<artifactId>springboot01-helloworld</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
</parent>
<name>springboot01-helloworld</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
</build>
</project>
1.3 Создать контроллер
package com.ly.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Author: LuYi
* Date: 2019/10/27 11:05
* Description: 描述
*/
@Controller
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return "Hello World";
}
}
1.4 Создайте стартовый класс
package com.ly;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Author: LuYi
* Date: 2019/10/27 11:05
* Description: 使用@SpringBootApplication将类标注成SpringBoot应用
*/
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
сканирование по умолчанию@SpringBootApplication
Также можно использовать пакет, в котором находится аннотация, и его подпакеты.@ComponentScan("com.ly.controller")
Аннотация для указания
1.5 Упаковка
<!--该插件可以将应用打包成一个可执行的jar包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Добавьте этот плагин, упакуйте приложение в исполняемый jar-пакет и выполните:java -jar jar文件
2. Проанализируйте HelloWorld
2.1 POM-файл
-
родительский проект
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.9.RELEASE</version> </parent>
-
Родительский проект родительского проекта: используется для управления версиями зависимостей в приложении SPRINGBOOT для контроля версий
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.9.RELEASE</version> <relativePath>../../spring-boot-dependencies</relativePath> </parent>
-
Зависимость: пройти
starter
Укажите зависимости<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
SpringBoot предоставляет множество пускателей (стартеров), которые соответствуют разным сценариям применения, при введении этих пускателей в проект будут импортированы зависимости соответствующих сценариев.
2.2 Стартовый класс
@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}
)}
)
-
@SpringBootApplication
Он отмечен на классе, указывая на то, что этот класс является классом запуска SpringBoot, и приложение SpringBoot запускается через метод Main этого класса.
-
@SpringBootConfiguration
Аннотация к классу, указывающая, что этот класс является классом конфигурации SpringBoot.
Иерархическая связь: SpringBootConfiguration——>@Configuration——>@Component
@Configuration: аннотация к классу, указывающая, что этот класс является классом конфигурации Spring, эквивалентным файлу конфигурации XML.
-
@EnableAutoConfiguration
включиАвтоматическая конфигурацияФункция, упрощающая предыдущую громоздкую конфигурацию
При запуске SpringBoot значения, указанные EnableAutoConfiguration в /META-INF/spring.factories, будут добавлены в контейнер как классы автоматической конфигурации.Эти значениякласс автоконфигурацииПоможет нам выполнить большую работу по настройке.
-
@ComponentScan
Аннотируется к классу с указанием пакета и его подпакетов для сканирования.
3. Быстро создать проект SpringBoot
1. Введение
SpringBoot быстро построить проект, используя пружинный инициализатор
2. Основные операции
-
Файл pom и основной класс программы генерируются автоматически, а бизнес-логика может быть написана напрямую.
-
Структура каталогов папки ресурсов
|-static 存放静态资源,如js,css,images |-template 存放模板引擎,如freemarker、thymeleaf等 |-application.properties SpringBoot应用的配置文件,可以修改默认设置
В-четвертых, файл конфигурации
1. Введение
Для SpringBoot существует два файла глобальной конфигурации по умолчанию:
- application.properties
- application.yml
Имя файла фиксировано и хранится в каталоге classpath:/ или classpath:/config/
Вы можете изменить конфигурацию Spring Boot по умолчанию, см.:docs.spring.IO/весенняя загрузка…
Примечание. Конфигурации SpringBoot 2.0 и 1.0 отличаются, и некоторые элементы конфигурации были удалены.
2. Использование YAML
2.1 Введение
YAML не является языком разметки. YAML специально используется для написания файлов конфигурации. Он ориентирован на данные и имеет мощное введение. Он больше подходит для файлов конфигурации, чем xml и свойства.
Файлы YAML имеют суффикс .yml или .yaml.
2.2 application.yml
server:
port: 8081 #写法:key: value 冒号后面必须有空格
servlet:
context-path: /springboot03/
2.3 Грамматические правила
- Деликатный случай
- Используйте отступ для обозначения иерархии
- Клавиша Tab не разрешена при отступе
- Количество отступов не имеет значения, но он должен быть выровнен слева от соответствующего уровня.
-
#
Указывает на примечание
2.4 Основное использование
YAML поддерживает три структуры данных:
- Литерал: одно неделимое значение (строка, число, логическое значение)
- Объект: набор пар ключ-значение.
- массив: набор значений по порядку
Использование трех структур данных:
1. Литералы: обычные значения, такие как числа, строки, логические значения.
number: 12.5
str: hello
name: 'tom cruise' #如字符串包含空格及特殊字符需要使用 引号 引起来
name: 'tom \n cruise' #不会对特殊字符进行转义 结果为:tom 换行 cruise
name: "tom \n cruise" #对特殊字符进行转义,会作为普通字符输出, 结果为 tom \n cruise
-
Объекты, также известные как Карты, содержат свойства и значения.
# 写法1:换行写 user: name: tom age: 20 sex: male # 写法2:行内写法 user: {name: tom, age: 20, sex: male}
- Массивы, такие как List, Set и т. д.
# 写法1: 一组短横线开头的行 names: - tom - jack - alice # 写法2: 行内写法 name: {tom,jack,alice}
3. Введите значения для свойств
Внедрить значения свойств в класс, загрузив файл конфигурации
3.1 Написание application.yml
user:
username: admin
age: 21
status: true
birthday: 2019/2/14
address:
province: 黑龙江省
city: 哈尔滨市
lists:
- list1
- list2
- list3
maps: {k1: v1,k2: v2}
3.2 Создание класса сущностей
User
package com.luyi.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* Author: LuYi
* Date: 2019/10/27 13:49
* Description: 通过加载配置文件为当前类中的属性注入值
*/
// 必须将当前类加入到容器
@Component
// 默认读取全局配置文件获取值,当前类中的所有属性与 user 进行绑定
@ConfigurationProperties(value = "user")
public class User {
private String username;
private Integer age;
private Boolean status;
private Date birthday;
private Address address;
private List<String> lists;
private Map<String, Object> maps;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<String> getLists() {
return lists;
}
public void setLists(List<String> lists) {
this.lists = lists;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
", status=" + status +
", birthday=" + birthday +
", address=" + address +
", lists=" + lists +
", maps=" + maps +
'}';
}
}
Address
package com.luyi.bean;
/**
* Author: LuYi
* Date: 2019/10/27 13:50
* Description: 描述
*/
public class Address {
private String province;
private String city;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
}
3.3 Тестирование
package com.luyi.springboot03config;
import com.luyi.bean.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Springboot03ConfigApplicationTests {
@Autowired
private User user;
@Test
void contextLoads() {
System.out.println(user);
}
}
3.4 Добавьте зависимости процессора файла конфигурации (необязательно)
<!--配置文件处理器,自动生成元数据信息,编写配置文件会有提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
3.5 Использование файла конфигурации свойств
user.username=alice
user.age=22
user.status=false
user.birthday=2019/10/27
user.address.province=黑龙江省
user.address.city=哈尔滨
user.lists=list1,list2,list3
user.maps.k1=v1
user.maps.k2=v2
Примечание. Кодировка UTF-8 используется по умолчанию в IDEA, а в файле свойств по умолчанию используется кодировка ASCII, поэтому есть искажения, которые можно устранить.
Приоритет: свойства> YML
3.6 Внедрение значений с помощью аннотации @Value
@Value("${user.username}")
private String username;
@Value("${user.age}")
private Integer age;
@Value("${user.status}")
private Boolean status;
@Value("${user.birthday}")
private Date birthday;
//@Value不支持复杂类型封装
private Address address;
@Value("${user.lists}")
private List<String> lists;
private Map<String, Object> maps;
Сравните @Value с @ConfigurationProperties:
- Первый можно вводить только с одним значением, а второй можно вводить партиями.
- Первый не поддерживает инкапсуляцию для сложных типов, второй поддерживает
4. Конфигурация многорекония
Различная информация о конфигурации может быть предоставлена для различных сред, таких как среда разработки, тестовая среда, производственная среда и т. Д.
Два пути:
- Создать несколько файлов свойств
- определить блок документации yml
4.1 Создание нескольких файлов свойств
шаг:
1. Создайте файлы свойств для разных сред
Имя файла должно соответствовать формату копия-xxx.properties
Application-dev.properties.
server.port=9991
приложение-test.properties
server.port=9992
приложение-prod.properties
server.port=9993
2. Укажите конфигурацию, которую необходимо активировать в application.properties
#指定要激活的配置
spring.profiles.active=prod
4.2 Определение блока документации yml
1. Используйте три тире, чтобы определить несколько блоков документов в yml
spring:
profiles: dev
server:
port: 9991
---
spring:
profiles: test
server:
port: 9992
---
spring:
profiles: prod
server:
port: 9993
2. Укажите среду для активации в первом блоке документа
spring:
profiles:
active: test
---
5. Загрузите внешние файлы конфигурации
5.1 Загрузите файл свойств свойств
Вопрос: @ConfigurationProperties по умолчанию считывает значение из файла глобальной конфигурации.Что делать, если вы хотите получить значение из файла пользовательских свойств?
Решение: используйте аннотацию @PropertySource для загрузки внешних файлов свойств.
// 必须将当前类加入到容器
@Component
//加载外部的属性文件
@PropertySource({"classpath:user.properties"})
// 默认读取全局配置文件获取值,当前类中的所有属性与 user 进行绑定
@ConfigurationProperties(value = "user")
public class User{
5.2 Загрузите файл конфигурации Spring
Вопрос: Если есть информация, которую нужно записать в файл xml, что мне делать, если я хочу загрузить файл xml
Решение: используйте @ImportResource для загрузки внешних файлов конфигурации.
5.3 Добавление компонентов с помощью аннотаций
Рекомендуется использовать полную аннотацию для добавления компонентов в контейнер Spring, @Configuration и @Bean.
/**
* Author: LuYi
* Date: 2019/10/28 14:49
* Description: 描述
*/
//添加在类上,表示这个类是一个配置类,相当于spring配置文件
@Configuration
public class SpringConfig {
//标注在方法上,用来向容器中添加组件,将方法的返回值添加到容器中,方法名作为bean的id
@Bean
public Address address(){
Address address = new Address();
address.setProvince("山东");
address.setCity("日照");
return address;
}
}
Пять, принцип автоматической настройки SpringBoot
1. Процесс исполнения
1. SpringBoot загружает основной класс конфигурации при запуске и использует @EnableAutoConfiguration для включения функции автоматической настройки.
2. @Import({AutoConfigurationImportSelector.class}) используется в @EnableAutoConfiguration для добавления в контейнер некоторых компонентов (классов автоматической настройки).
Просмотрите метод selectImports в классе AutoConfigurationImportSelector, а затем щелкните метод `getCandidateConfigurations в методе getAutoConfigurationEntry.
Загружается в SpringFactory с помощью метода loadFactoryNames в getCandidateConfigurations,
Затем загрузите через classLoaderMETA-INF/spring.factories
конфигурации, получите значение, соответствующее EnableAutoConfiguration (spring-boot-autoconfigure-2.1.9.RELEASE.jar) из конфигурации.
Добавьте эти классы автоконфигурации (xxxAutoConfiguration) в контейнер.
3. Завершите функцию автоматической настройки через класс автоматической настройки.
2. Принципиальный анализ
Например, к httpenCodingautoconfigguration, ранее настроен в Web.xml HARDERENCODINGFILTER FILTER
//表示这是一个配置类,相当于以前编写的Spring配置文件
@Configuration
//启用HttpProperties类的ConfigurationProperties功能,通过配置文件为属性注入值,并将其添加到容器中
@EnableConfigurationProperties({HttpProperties.class})
//当该应用是web应用时才生效
@ConditionalOnWebApplication(
type = Type.SERVLET
)
//必须包含CharacterEncodingFilter类才生效
@ConditionalOnClass({CharacterEncodingFilter.class})
//如果配置文件中有spring.http.encoding选项则该配置生效,否则不生效。但是默认已经生效了
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
private final Encoding properties;
//将容器中的HttpProperties注入
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}
//将返回的filter添加到容器中,作为bean
@Bean
//如果容器中没有这个bean才会生效
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
return filter;
}
//从配置文件中获取指定的值,然后绑定到指定的属性值
@ConfigurationProperties(
prefix = "spring.http"
)
public class HttpProperties {
private Charset charset;
private Boolean force;
private Boolean forceRequest;
private Boolean forceResponse;
private Map<Locale, Charset> mapping;
Уведомление:
- Судя по текущей ситуации, решите, производится ли класс конфигурации или нет.Если условия не соблюдены, автоматическая конфигурация не вступит в силу.
- Свойства класса автоматической настройки xxAutoConfiguration получаются из соответствующего класса xxProperties
- Информация в классе xxProperties вводится и связывается через файл конфигурации, а значение атрибута может быть указано через файл конфигурации.
3. Резюме
- SpringBoot загружает большое количество классов автоматической настройки при запуске
- Добавление компонентов в контейнер через автоконфигурацию
- Благодаря этим компонентам многие функции автоматизированы, что упрощает настройку.
Вы можете проверить соответствие классов автоконфигурации, включив режим отладки
#开启debug模式
debug=true
6. Веб-разработка
1. Введение
Шаги по разработке веб-приложений с помощью SpringBoot:
1. Создайте проект SpringBoot и добавьте соответствующий стартер
2. Укажите необходимый небольшой объем конфигурации в конфигурационном файле
3. Напишите бизнес-код
Класс автоматической настройки веб-разработки WebMvcAutoConfiguration
2. Картирование статических ресурсов
2.1 Статическое местоположение ресурсов
Просмотр WebMvcAutoConfiguration——> addResourceHandlers()——>getStaticLocations()——>staticLocations
Расположение по умолчанию для статических ресурсов
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
Доступ к статическим ресурсам можно получить через указанную выше папку.
Вы также можете самостоятельно указать доступное местоположение в файле конфигурации.
# 指定静态资源的位置 存放在根目录下的public文件夹中
spring.resources.static-locations=classpath:/public
2.2 Страница приветствия
Просмотр WebMvcAutoConfiguration->welcomePageHandlerMapping() -> getWelcomePage()
Поместите страницу index.html в любую папку статических ресурсов.
2.3 Иконки веб-сайтов
Просмотр WebMvcAutoConfiguration—> Внутренний класс FaviconConfiguration—> faviconHandlerMapping
Поместите favicon.ico в любую папку статических ресурсов
Семь, шаблонизатор
1. Введение
В настоящее время рекомендуется использовать механизм шаблонов для веб-разработки на Java, и не рекомендуется использовать страницы jsp.
- Недостатки jsp: По сути, сервлет необходимо компилировать в фоновом режиме, что менее эффективно.
- Механизм шаблонов: не нужно компилировать, быстро
Часто используемые шаблонизаторы: Freemarker, Thymeleaf и т. д.
SpringBoot рекомендует Thymeleaf и по умолчанию не поддерживает jsp, потому что jsp должен быть упакован как военный пакет.
Дополнение: текущее Mainstream Web Development рекомендует разделение передних и задних концов, и передний конец использует MVVM Framework, Vue.js, угловые, реагирующие и т. Д.
2. Использование тимьяна
шаг:
1. Добавьте зависимости Thymeleaf
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2. Поместите html-страницу под шаблоны
К HTML-коду в шаблонах нельзя получить прямой доступ. Вам нужно использовать контроллер, чтобы перейти и отобразить его с помощью Thymeleaf.
ThymeleaPautoconfiguration-> Thymeleafproperties.
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
Префикс SLICING по умолчанию и суффикс
3. Используйте тимьян
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>success</h2>
<!--使用th:text属性设置元素中的文本,表达式:${}可以获取作用域中的数据-->
<p th:text="${name}"></p>
</body>
</html>
4. После изменения страницы позвольте ему вступить в силу в режиме реального времени.
Поскольку тимелеаф по умолчанию включает кеширование, отключите кеширование
#禁用thymeleaf的缓存
spring.thymeleaf.cache=false
Дополнение: Также необходимо включить автоматическую компиляцию идеи, идея не будет компилироваться автоматически при сохранении по умолчанию.
3. Грамматические правила
3.1 Общие свойства
-
й:текст, й:uтекст
Установите текстовое содержимое в элементе
th:text экранирует специальные символы, эквивалентные встроенным [[${ }]]
TH: otext не избежать специальных символов, эквивалентных встроенному [($ {})]]
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--th:text、th:utext--> <div th:text="${hello}">aaa</div> <div th:utext="${hello}">bbb</div> <!--使用内联方式,可以在文本前后添加内容--> <div>[[${hello}]]aaa</div> <div>[(${hello})]bbb</div> </body> </html>
-
TH: нативные свойства HTML
Используется для замены значения указанного собственного атрибута html.
@RequestMapping("/test2") public String test2(Model model){ model.addAttribute("hello", "<mark>你好</mark>"); model.addAttribute("id", "mydiv"); model.addAttribute("title", "this is a div"); return "result"; }
<!--th:html原生属性--> <div id="div1" title="这是一个div" th:id="${id}" th:title="${title}">div</div>
-
й:если, й:если, й:переключатель, й:случай
Условное суждение, подобное if
<!--th:if、th:unless、th:switch、th:case--> <div th:if="${age>=18}">成年</div> <p th:unless="${age<18}">成年</p> <p th:switch="${role}"> <span th:case="student">学生</span> <span th:case="teacher">老师</span> <span th:case="*">其他</span> </p> <hr>
-
th:each
петля, аналогичная для каждого
<!--th:each--> <ul> <li th:each="name:${names}" th:text="${name}"></li> </ul>
-
th: объект, th: поле
Для привязки объектов данных формы привяжите форму к параметру JavaBean контроллера, часто с th:field
Используется вместе, его необходимо использовать в сочетании с выражением выбора * {}
<!--th:object、th:field--> <h2>修改用户信息</h2> <!--th:object指定对象,th:field指定属性--> <form action="modify" method="post" th:object="${user}"> 编号:<input type="text" th:field="*{id}" readonly> <br> 姓名:<input type="text" th:field="*{name}"> <br> 年龄:<input type="text" th:field="*{age}"> <br> <input type="submit" value="修改"> </form>
-
th:fragment
Объявите фрагменты кода, часто используемые для представления верхнего и нижнего колонтитула страницы.
<!--th:fragment--> <header th:fragment="head"> 这是页面的头部,导航 </header>
-
й: включить, й: вставить, й: заменить
Добавьте фрагменты кода, похожие на jsp:include.
<!--th:include、th:insert、th:replace--> <!--引入templates/include下的header.html页面中的fragment为head的片段--> <div th:include="include/header::head"></div>
разница между тремя
th:include сохранит свои собственные теги, а не теги th:fragment (устарели после Thymeleaf 3.0)
th:insert сохраняет свою собственную метку, а также сохраняет метку th:fragment
th:relpace не сохраняет собственную метку, сохраните метку thfragment
3.2 выражения
-
${} переменное выражение
Получить свойства и методы объекта
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--获取对象的属性、方法--> <div th:text="${user.name}"></div> <div th:text="${user['age']}"></div> <div th:text="${users[1].name}"></div> <!--<div th:text="${users.size()}"></div>--> <div>[[${users.size()}]]个</div> </body> </html>
Используйте встроенные базовые объекты, такие как сеанс и приложение.
<!--使用内置基本对象--> <div th:text="${session.sex}"></div> <div th:text="${application.hobby}"></div>
Используйте встроенные служебные объекты, такие как #strings, #dates, #arrays, #lists, #maps и т. д.
<!--使用内置的工具对象--> <div th:text="${#strings.startsWith(user.name, 't')}"></div> <div th:text="${#strings.substring(user.name, 0, 2)}"></div> <div th:text="${#strings.length(user.name)}"></div> <div th:text="${#dates.createNow()}"></div> <div th:text="${#dates.create(2018, 10, 14)}"></div> <div th:text="${#dates.format(birthday, 'yyyy-MM-dd HH:mm:ss')}"></div>
-
} * {Выберите выражение (выражение звездочка)
<!--*{}选择表达式--> <div th:object="${user}"> <div th:text="*{id}"></div> <div th:text="*{name}"></div> <div th:text="*{age}"></div> </div>
-
@{} URL-выражение
<head> <meta charset="UTF-8"> <title>Title</title> <!--url表达式引入css文件--> <link rel="stylesheet" th:href="@{/css/style.css}"> </head> <!--url表达式--> <a th:href="@{/findUser(name=${user.name})}">查询指定的用户信息</a> <a href="product/list.html" th:href="@{/product/list}">商品列表</a> <script th:src="@{/js/common.js}"></script>
-
оператор
eq gt le == != тернарный оператор
4. Горячее развертывание
Используйте инструменты разработки, предоставляемые SpringBoot, для горячего развертывания.
Принцип: мониторинг изменений в файлах в пути к классам в режиме реального времени, автоматический перезапуск в случае изменений.
настроить: добавить зависимости devtools
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<!--该依赖不传递-->
<optional>true</optional>
</dependency>
Восемь, расширьте функцию SpringMVC по умолчанию.
1. Введение
Ранее в SpringMVC переходы между представлениями и перехватчики можно было выполнять с помощью следующего кода:
<mvc:view-controller path="/showLogin" view-name="login"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean class="com.luyi.interceptor.HelloInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
Конфигурация SpringBoot по умолчанию не предоставляет вышеуказанных функций по умолчанию, вам необходимо расширить ее самостоятельно, используя интерфейс WebMvcConfigurer
2. Основные операции
Шаги:
1. Определите класс конфигурации, реализующий интерфейс WebMvcConfigurer.
2. Реализовать требуемый метод
/**
* Author: LuYi
* Date: 2019/10/29 17:58
* Description: 扩展默认的SpringMVC的功能
* 要求:
* 1.将该类标记为配置类
* 2.实现WebMvcConfigurer接口
* 3.根据需要实现接口中相应的方法
*
* 注意:这个接口中的方法都添加了jdk1.8中的default方法修饰,不强制实现所有方法(jdk1.8新特性)
* 在SpringBoot1.0中是继承WebMvcConfigurerAdapter类,SpringBoot2.0是基于jdk1.8的,
* 所以通过实现WebMvcConfigurer的方式
*/
//将该类设置为配置类
@Configuration
public class CustomMvcConfig implements WebMvcConfigurer {
//添加ViewController
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//将访问login页面的url设置为showLogin
registry.addViewController("/showLogin").setViewName("login");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/test2");
}
}
9. Глобальная обработка исключений
1. Введение
Когда в программе возникает исключение, выполняется глобальная обработка.Информация об исключении SpringBoot по умолчанию запрашивает:Whitelabel Error Page
Два пути:
- Определить кодовую страницу ошибки
- Определить уведомление об исключении
2. Определите кодовую страницу ошибки
Создать错误状态码.html
страницу, поместите ее в каталог templates/error, при возникновении ошибки он автоматически перейдет в этот каталог, чтобы найти соответствующую страницу ошибки
можно создать например4xx.html
или5xx.html
страницу, чтобы сопоставить все ошибки этого типа (предпочтительнее будут точные совпадения
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>5xx错误</h2>
<h3>状态码:[[${status}]]</h3>
<h3>异常消息:[[${message}]]</h3>
<h3>错误提示:[[${error}]]</h3>
<h3>时间戳:[[${timestamp}]]</h3>
</body>
</html>
3. Определите уведомление об исключении
/**
* Author: LuYi
* Date: 2019/10/29 18:45
* Description: 异常通知:用来处理全局异常
*/
@ControllerAdvice
public class ExceptionAdvice {
@ExceptionHandler(ArithmeticException.class)
public String arithmetic(Exception e){
System.out.println("警报:程序出现异常,发短信:" + e.getMessage());
return "error/5xx";
}
@ExceptionHandler(Exception.class)
public String exception(Exception e){
System.out.println("警报:程序出现异常,发邮件:" + e.getMessage());
return "error/5xx";
}
}
10. О контейнерах сервлетов
1. Введение
SpringBoot по умолчанию имеет встроенный сервлет: Tomcat
Вопрос: SpringBoot по умолчанию запускает встроенный контейнер Servlet как jar-пакет.Файла web.xml нет.Как зарегистрировать три компонента сервлета: Servlet, Filter, Listener
Решение: настроив конфигурацию сервлета, используйте ServletRegistrationBean, FilterRegistrationBean, ServletListenerRegistrationBean.
2. Зарегистрируйте компонент сервлета
Шаги:
1. Определите класс конфигурации
2. Настройте способ зарегистрировать компонент
/**
* Author: LuYi
* Date: 2019/10/29 19:12
* Description: 自定义Servlet配置
*/
//将该类声明为配置类
@Configuration
public class CustomServletConfig {
//将方法返回值放到Spring容器
@Bean
public ServletRegistrationBean myServlet(){
ServletRegistrationBean<Servlet> registrationBean = new ServletRegistrationBean<>();
//对MyServlet进行注册
registrationBean.setServlet(new MyServlet());
ArrayList<String> urls = new ArrayList<>();
urls.add("/myServlet");
registrationBean.setUrlMappings(urls);
return registrationBean;
}
//注册Filter
@Bean
public FilterRegistrationBean myFilter(){
FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
//注册filter
registrationBean.setFilter(new MyFilter());
registrationBean.addUrlPatterns("/showLogin", "/test1");
return registrationBean;
}
//注册Listener
@Bean
public ServletListenerRegistrationBean myListener(){
ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>();
registrationBean.setListener(new MyListener());
return registrationBean;
}
}
3. Используйте внешний контейнер сервлета
3.1 Преимущества и недостатки
Используя встроенный контейнер сервлетов:
Преимущества: простота в использовании, упаковать приложение в пакет jar
Недостатки: не поддерживает jsp, низкая настраиваемость
Использование внешнего контейнера сервлета
Преимущества: поддержка jsp, широкие возможности настройки
Недостатки: нужно упаковать приложение в военный пакет
3.2 Этапы работы
Шаги:
1. Создайте военный проект Maven
Есть следующие три изменения
1. Способ упаковки становится войной
<packaging>war</packaging>
2. Настройте встроенную область действия tomcat, как указано
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
3. Определяет подкласс SpringBootServletInitializer.
/**
* 要求:
* 1.必须继承SpringBootServletInitializer
* 2.重写configure()方法
* 3.调用SpringApplicationBuilder的sources()方法,传入主程序类的
*/
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Springboot05WarApplication.class);
}
}
2. Создайте структуру веб-каталога
3. Настройте префикс и суффикс
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
4. Настройте Tomcat
Чтобы использовать версию Tomcat, необходимую для SpringBoot
Одиннадцать, доступ к данным SpringBoot
1.JDBC
Шаги:
1. Создайте проект и выберите следующие шаблоны: web, jdbc, mysql
2. Настройте информацию о подключении к базе данных
#指定数据库连接参数
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
#指定数据源
spring.datasource.type=org.apache.commons.dbcp.BasicDataSource
3. Тест
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
class Springboot06JdbcApplicationTests {
@Autowired
private DataSource dataSource;
@Test
void contextLoads() throws SQLException {
System.out.println("---------------------------");
System.out.println("DataSource的类型: " + dataSource.getClass());
System.out.println("Connection的连接: " + dataSource.getConnection());
}
}
4. Настройте параметры пула соединений
spring.datasource.initialSize=10
spring.datasource.maxActive=100
spring.datasource.minIdle=5
spring.datasource.maxWait=50000
Проблема: Добавление вышеуказанных параметров не вступает в силу, так как SpringBoot не поддерживает эти параметры по умолчанию (DataSourceProperties)
Решение: Пользовательская конфигурация источника данных
/**
* Author: LuYi
* Date: 2019/10/30 16:09
* Description: 描述
*/
@Configuration
public class DatasourceConfig {
@Bean
//从配置文件中读取spring.datasource属性,并注入给数据源的属性
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
return new BasicDataSource();
}
}
5. Используйте JdbcTemplate для работы с базой данных
/**
* Author: LuYi
* Date: 2019/10/30 16:17
* Description: 描述
*/
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private JdbcTemplate jdbcTemplate;
@RequestMapping("/findAll")
@ResponseBody
public List<Map<String, Object>> findAll(){
String sql = "select * from t_user";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
return list;
}
}
2.MyBatis
2.1 Основные шаги
1. Для создания проекта сначала выберите следующие модули: web, mybatis
2. Настройте источник данных
#配置DataSource
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: root
initialSize: 5
maxActive: 100
minIdle: 3
maxWait: 50000
#配置MyBatis
mybatis:
type-aliases-package: com.luyi.pojo
mapper-locations: classpath:mapper/*.xml
3. Напишите Mapper, Service, Controller
4. Настройте класс конфигурации MyBatisConfig
/**
* Author: LuYi
* Date: 2019/10/30 16:57
* Description: 描述
*/
@Configuration
//扫描MyBatis接口所在的包
@MapperScan("com.luyi.mapper")
public class MyBatisConfig {
@Bean
//加载主配置文件,注入配置信息
@ConfigurationProperties(prefix = "spring.datasource")
public DruidDataSource druidDataSource(){
return new DruidDataSource();
}
}
2.2 Настройка плагина подкачки PageHelper
Шаги:
1. Добавьте зависимость PageHelper
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
2. Настройте свойства PageHelper
#配置PageHelper
pagehelper:
helper-dialect: mysql
3. Используйте PageHelper
@Override
public PageInfo<User> findByPage(int pageNum, int pageSize) {
//使用PageHelper设置分页
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.selectAll();
PageInfo<User> pageInfo = new PageInfo<>(users);
return pageInfo;
}
2.3 Использование MyBatis Plus
Ссылка:mp.baomidou.com/
Шаги:
1. Добавьте зависимость MyBatis Plus
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
2. Настройте глобальный файл конфигурации
#配置DataSource
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: root
initialSize: 5
maxActive: 100
minIdle: 3
maxWait: 50000
#配置MyBatis Plus
mybatis-plus:
mapper-locations: classpath:mapper/*Mapper.xml
type-aliases-package: com.luyi.pojo
global-config:
db-config:
#主键类型
id-type: auto
#字段策略
field-strategy: not_empty
#驼峰下划线转换
table-underline: true
#全局表前缀
table-prefix: t_
#刷新mapper神器
refresh-mapper: true
3 Настройка MyBatis Plus
/**
* Author: LuYi
* Date: 2019/10/31 9:59
* Description: 描述
*/
@Configuration
@MapperScan("com.luyi.mapper")
public class MyBatisPlusConfig {
/**
* 分页插件,自动识别数据库类型
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
return new DruidDataSource();
}
}
4. Написать Mapper, унаследовать BaseMapper
/**
* Author: LuYi
* Date: 2019/10/31 10:07
* Description: 继承BaseMapper接口
*/
public interface UserMapper extends BaseMapper<User> {
}
5. Тест
@RunWith(SpringRunner.class)
@SpringBootTest
class Springboot08MpApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
}
@Test
public void add(){
User user = new User();
user.setUsername("xxx");
user.setPassword("111");
userMapper.insert(user);
System.out.println("-------------" + user);
}
@Test
public void removeById(){
int i = userMapper.deleteById(3);
System.out.println(i);
}
@Test
public void modifyById(){
User user = new User();
user.setId(6);
user.setUsername("zhangsan");
user.setPassword("123");
userMapper.updateById(user);
}
@Test
public void findById(){
User user = userMapper.selectById(1);
System.out.println(user);
}
@Test
public void findByCondition(){
//定义条件构造器,用来封装查询条件
QueryWrapper<User> wrapper = new QueryWrapper<>();
// wrapper.eq("username", "tom");
wrapper.like("username", "%a%");
List<User> users = userMapper.selectList(wrapper);
for (User user : users) {
System.out.println(user);
}
}
@Test
public void findByPage(){
Page<User> page = new Page<>(2, 2);
QueryWrapper<User> wrapper = new QueryWrapper<>();
IPage<User> userIPage = userMapper.selectPage(page, wrapper.select("id", "username", "password"));
assertThat(page).isSameAs(userIPage);
System.out.println("总条数---->" + userIPage.getTotal());
System.out.println("当前页数---->" + userIPage.getCurrent());
System.out.println("当前每页显示数---->" + userIPage.getSize());
System.out.println(userIPage.getRecords());
System.out.println("----------自带分页----------");
}
}
Добавлено: использование ломбока.
шаг:
1. Добавьте зависимости
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
2. Используйте аннотации, предоставленные lombok
/**
* Author: LuYi
* Date: 2019/10/30 16:32
* Description: Lombok的使用
* Lombok提供了许多注解,标注在类上或者属性上
*/
@Getter
@Setter
@ToString
@Data //相当于以上注解
@TableName(value = "t_user") //指定当前数据库表的名称
public class User implements Serializable {
private Integer id;
private String username;
private String password;
}
3. Установите плагин lombok в Idea
Поскольку в исходном коде нет определения геттера/сеттера, Idea не может его распознать, вы можете установить плагин lombok, чтобы решить эту проблему.
12. SpringBoot интегрирует Redis
1. Введение
Redis — это база данных в памяти, которую можно использовать в качестве кэша, промежуточного программного обеспечения сообщений, базы данных «ключ-значение» и т. д.
2. Операция
Шаги:
1. Добавьте зависимости
Примечание. Клиент Redis, используемый в SpringBoot1.0, — это Jedis, а Lettuce используется в SpringBoot2.0.
<!--整合Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<!--SpringBoot2.0使用的Redis客户端时Lettuce-->
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
2. Настройте Redis
#redis配置
spring.redis.host=192.168.52.128
spring.redis.port=6379
spring.redis.database=0
spring.redis.jedis.pool.max-active=100
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.min-idle=3
3. Основное использование
Используйте классы инструментов, предоставляемые SpringDataRedis: StringRedisTemplate, RedisTemplate.
Инкапсулировать JsonUtils
/**
* Author: LuYi
* Date: 2019/10/31 17:37
* Description: Json工具类,基于jackson
*/
public class JsonUtils {
//获取jackson对象
private static ObjectMapper objectMapper = new ObjectMapper();
/**
* 将对象转换为Json字符串
*/
public static String objectToJson(Object obj){
try {
//将对象转换为Json字符串
String jsonStr = objectMapper.writeValueAsString(obj);
return jsonStr;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将Json字符串转换为对象
*/
public static <T> T jsonToObject(String jsonStr, Class<T> clazz){
try {
T t = objectMapper.readValue(jsonStr, clazz);
return t;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
тест
@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot09RedisApplicationTests {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Test
public void contextLoads() {
}
/**
* 使用StringRedisTemplate
* Redis数据类型:String、List、Set、ZSet、Hash
*/
@Test
public void test1(){
/**
* 操作redis
*/
// ValueOperations<String, String> value = stringRedisTemplate.opsForValue();
// ListOperations<String, String> list = stringRedisTemplate.opsForList();
// SetOperations<String, String> set = stringRedisTemplate.opsForSet();
// ZSetOperations<String, String> zset = stringRedisTemplate.opsForZSet();
// HashOperations<String, Object, Object> hash = stringRedisTemplate.opsForHash();
/**
* 操作String
*/
// stringRedisTemplate.opsForValue().set("username", "admin");
// System.out.println(stringRedisTemplate.opsForValue().get("username"));
/**
* 操作List
*/
// stringRedisTemplate.opsForList().leftPush("name", "tom");
// stringRedisTemplate.opsForList().leftPushAll("name", "aaa", "bbb", "ccc");
// System.out.println(stringRedisTemplate.opsForList().range("name", 0, -1));
/**
* 存储对象
*/
User user = new User();
user.setId(1001);
user.setUsername("tom");
user.setPassword("123");
//将对象转换为json格式
String jsonStr = JsonUtils.objectToJson(user);
System.out.println(jsonStr);
stringRedisTemplate.opsForValue().set("user", jsonStr);
//获取jsonStr
String str = stringRedisTemplate.opsForValue().get("user");
//将str转换为对象
User u = JsonUtils.jsonToObject(str, User.class);
System.out.println(u);
}
/**
* 使用redisTemplate
*/
@Test
public void test2(){
redisTemplate.opsForValue().set("sex", "male");
String sex = redisTemplate.opsForValue().get("sex");
System.out.println(sex);
}
}