Руководство по обзору основ Spring Boot 2.X

Java

Дополнение к знаниям SpringBoot2

@Configuration & @Bean

В отличие от традиционного Spring, SpringBoot не поддерживает использование файлов конфигурации, а использует классы конфигурации вместо файлов конфигурации, поэтому эта аннотация используется для указания класса как класса конфигурации:

@Configuration
public class MyConfig {

    @Bean("user")
    public User getUser(){
        return new User("张三",20);
    }
}

Используйте этот метод для регистрации компонента в классе конфигурации, и его действие будет эквивалентно следующему:

<bean id="user" class="com.wwj.springboot.bean.User">
  <property name="name" value="张三"/>
  <property name="age" value="20"/>
</bean>

Следует отметить, что SpringBoot будет использовать имя метода в качестве идентификатора компонента по умолчанию, и его также можно использовать в@Bean()Укажите значение value как идентификатор компонента.

@Import

В Spring мы можем использовать аннотации @Component, @Controller, @Service, @Repository для регистрации компонентов, а для некоторых сторонних классов мы не можем добавить эти аннотации в класс, для этого мы можем использовать аннотацию @Import Register it с контейнером.

@Configuration(proxyBeanMethods = true)
@Import(User.class)
public class MyConfig {
}

Идентификатор компонента, зарегистрированный аннотацией @Import, является полным именем класса.

@Conditional

Эта аннотация представляет собой аннотацию условной сборки, которая широко используется в нижнем слое SpringBoot.Есть много аннотаций, производных от этой аннотации:image.pngВот примеры @ConditionalOnBean и @ConditionalOnMissingBean. Функция аннотации @ConditionalOnBean заключается в том, чтобы определить, существует ли указанный bean-компонент в текущем контейнере, и если да, то он вступит в силу, например:

@Configuration
public class MyConfig {

    @Bean("dog")
    public Dog getDog(){
        return new Dog();
    }

    @Bean("user")
    @ConditionalOnBean(name = "dog")
    public User getUser(){
        return new User("张三",20);
    }
}

Если это так, SpringBoot сначала определит, есть ли уже идентификатор в контейнере, прежде чем регистрировать объект User.dogОбъект , если он существует, будет создан, иначе не будет создан. У аннотации @ConditionalOnBean есть три способа определить, существует ли уже указанный объект в контейнере.Помимо оценки идентификатора компонента, она также может определить полное имя класса компонента:

@Bean("user")
@ConditionalOnBean(type = "com.wwj.springboot.bean.Dog")
public User getUser(){
    return new User("张三",20);
}

Вы также можете судить о типе компонента по:

@Bean("user")
@ConditionalOnBean(value = Dog.class)
public User getUser(){
    return new User("张三",20);
}

В частности, поскольку код выполняется сверху вниз, особое внимание следует уделить порядку регистрации компонентов, например:

@Configuration
public class MyConfig {

    @Bean("user")
    @ConditionalOnBean(value = Dog.class)
    public User getUser(){
        return new User("张三",20);
    }

    @Bean("dog")
    public Dog getDog(){
        return new Dog();
    }
}

В этой программе SpringBoot сначала зарегистрирует объект «Пользователь», а в это время объект «Собака» еще не зарегистрирован, поэтому объект «Пользователь» не может быть зарегистрирован.

Функция аннотации @ConditionalOnMissingBean прямо противоположна функции аннотации @ConditionalOnBean.Она будет определять, существует ли указанный бин в текущем контейнере.Если он не существует, то он вступит в силу, иначе он не будет принят. эффект.

Эти аннотации могут быть помечены на методы, а также могут действовать на классы.При пометке на классы при выполнении условий будут действовать все методы регистрации класса конфигурации, если условия не выполнены, все методы регистрации класса конфигурации не установится..

@Configuration
@ConditionalOnBean(value = Dog.class)
public class MyConfig {

    @Bean("user")
    public User getUser(){
        return new User("张三",20);
    }

    @Bean("dog")
    public Dog getDog(){
        return new Dog();
    }
}

@ImportResource

Эта аннотация используется для импорта ресурсов, например, теперь есть файл конфигурации Spring:

<?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="ls" class="com.wwj.springboot.bean.User">
        <property name="name" value="李四"/>
        <property name="age" value="25"/>
    </bean>
    
    <bean id="tom" class="com.wwj.springboot.bean.Dog">
        <property name="name" value="tom"/>
        <property name="age" value="3"/>
    </bean>
</beans>

Если вы хотите преобразовать его в класс конфигурации, лучше сказать, что код меньше.Когда в файле конфигурации прописано много бинов, явно не лучший способ использовать ручной метод.По этой причине, SpringBoot предоставляет аннотацию @ImportResource, которая может импортировать файл конфигурации Spring непосредственно в контейнер для автоматического завершения регистрации компонента.

@Configuration
@ImportResource("classpath:bean.xml")
public class MyConfig {

    @Bean("user")
    public User getUser(){
        return new User("张三",20);
    }

    @Bean("dog")
    public Dog getDog(){
        return new Dog();
    }
}

@ConfigurationProperties

Конфигурация привязки для аннотаций, а также большое количество используемых базовых SpringBoot. Сначала прописаны два ключа в конфигурационном файле:

user.name=zhangsan
user.age=30

Затем используйте эту аннотацию, чтобы связать ее с классом User:

@Component
@ConfigurationProperties(prefix = "user")
public class User {

    private String name;
    private int age;

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Но результаты оказались несколько неожиданными:

User{name='Administrator', age=30}

Это потому, что мы будем префиксprefixОн указан для пользователя, и пользователь может дублировать конфигурацию нашей системы, что приводит к этой проблеме.На данный момент нам нужно только изменить префикс:

@Component
@ConfigurationProperties(prefix = "users")
public class User {

    private String name;
    private int age;

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Префикс модифицируется, и содержимое конфигурационного файла тоже нужно модифицировать соответствующим образом:

users.name=zhangsan
users.age=30

Следует отметить, что если вы хотите реализовать привязку конфигурации, вы должны зарегистрировать класс для привязки в контейнере, например, используя аннотацию @Component.Конечно, SpringBoot также предоставляет аннотацию для использования с ним, а именно:@EnableConfigurationProperties.

Эта аннотация должна быть отмечена в классе конфигурации:

@Configuration
@EnableConfigurationProperties(User.class)
public class MyConfig {
}

Функция заключается в том, чтобы включить функцию привязки конфигурации указанного класса, ее нижний слой фактически реализуется через аннотацию @Import, в настоящее время классу User не нужно ее регистрировать в контейнере:

@ConfigurationProperties(prefix = "users")
public class User {

    private String name;
    private int age;

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

SpringBoot автоматически привяжет значение свойства к классу User и зарегистрирует его в контейнере.

Принцип автоматической настройки SpringBoot

С предыдущей основой аннотаций мы можем глубже понять принцип автоматической настройки SpringBoot, основанный на этих мощных аннотациях.

Давайте сначала рассмотрим аннотации к основному классу запуска:

@SpringBootApplication
public class SpringbootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }
}

Просматривая исходный код, вы можете увидеть, что аннотация @SpringBootApplication на самом деле состоит из трех аннотаций:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
}

Нижний уровень @SpringBootConfiguration — это аннотация @Configuration, которая указывает, что основной класс запуска является классом конфигурации, а @ComponentScan — это аннотация сканирования, которая по умолчанию сканирует компоненты в текущем пакете основного класса запуска и его подпакетов. ; наиболее критична @EnableAutoConfiguration Annotated, аннотация реализует автоматическую настройку.

Глядя на исходный код аннотации @EnableAutoConfiguration, вы обнаружите, что он состоит из двух аннотаций:

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
}

Продолжим просмотр исходного кода аннотации @AutoConfigurationPackage:

@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}

Аннотация @Import нам очень знакома, она используется для импорта компонента, но она особенная:

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    Registrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
    }

    public Set<Object> determineImports(AnnotationMetadata metadata) {
        return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
    }
}

Здесь в компоненте Registrar есть два метода: он используется для импорта ряда компонентов, а аннотация косвенно аннотируется в классе запуска, поэтому он перенесет все компоненты в пакет, где находится основной класс запуска и его подпакеты прописаны в контейнере.

Далее мы продолжаем рассматривать вторую синтетическую аннотацию @EnableAutoConfiguration: @Import({AutoConfigurationImportSelector.class}) Эта аннотация также регистрирует компонент в контейнере, читаем исходный код компонента:

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }
}

Этот метод используется для выбора компонентов для импорта.Этот метод вызывает метод getAutoConfigurationEntry() для получения компонентов, которые необходимо импортировать, поэтому мы рассмотрим этот метод:

protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    if (!this.isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    } else {
        AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
        List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
        configurations = this.removeDuplicates(configurations);
        Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
        this.checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = this.getConfigurationClassFilter().filter(configurations);
        this.fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
    }
}

Достигнув точки останова в методе getCandidateConfigurations(), после выполнения отладки мы можем обнаружить, что в коллекции конфигураций было получено 127 классов автоматической конфигурации:image.pngТак откуда берутся эти классы? Нам нужно изучить, что делает метод getCandidateConfigurations(), который на самом деле вызывает метод loadFactoryNames():

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());

Последний вызов — метод loadSpringFactories() для получения коллекции Map:

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
    if (result != null) {
        return result;
    } else {
        try {
            Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
            LinkedMultiValueMap result = new LinkedMultiValueMap();
        }
    }
}

Как видите, на самом деле это компонент, полученный из файла META-INF/spring.factories, мы можем посмотреть на импортированные зависимости:image.pngВ каталоге META-INF файла spring-boot-autoconfigure-2.3.7.RELEASE.jar есть файл spring.factories, откройте его, чтобы увидеть содержимое файла:

# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
......

Содержимое файла - это собственно компоненты, которые необходимо зарегистрировать в начале. Эти компоненты представляют собой некие классы конфигурации. Как только проект запустится, SpringBoot зарегистрирует все эти классы конфигурации в контейнере.

Включить автоматическую настройку по запросу

Хотя класс конфигурации будет автоматически зарегистрирован в контейнере SpringBoot, не каждый класс конфигурации будет действовать по умолчанию. SpringBoot включит автоматическую настройку по мере необходимости в соответствии с текущим сценарием. Например, класс автоматической настройки механизма шаблонов Thymeleaf:image.pngФункция аннотации @ConditionalOnClass — проверить, есть ли в текущем проекте указанный файл .class, и если да, то он вступит в силу, иначе — не вступит в силу. Поскольку мы не вводили зависимости Thymeleaf, TemplateMode.class и SpringTemplatengine.class не существуют, поэтому ThymeleafAutoCinfiguration не вступит в силу.

Изменить конфигурацию по умолчанию

Поскольку SpringBoot помогает нам с автоматической настройкой, как мы можем изменить его конфигурацию по умолчанию для некоторых специальных сценариев приложений? Если вы не понимаете принцип конфигурации SpringBoot, то, когда вам нужно изменить конфигурацию по умолчанию, вы должны быть беспомощны. Мы можем найти конфигурацию SpringMVC по умолчанию и посмотреть, как SpringBoot помогает нам ее настроить:image.pngРанее также была введена аннотация @EnableConfigurationPropertie(WebMvcProperties.class), которая используется для включения привязки конфигурации указанного класса, поэтому давайте взглянем на класс WebMvcProperties:

@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
}

Префикс привязки конфигурации — spring.mvc, поэтому, если мы хотим изменить конфигурацию SpringBoot по умолчанию, мы должны написать префикс как spring.mvc, Что касается того, какие конфигурации мы можем изменить, нам нужно только проверить, какие переменные-члены в классе. , например:

public static class View {

    /**
		 * Spring MVC view prefix.
		 */
    private String prefix;

    /**
		 * Spring MVC view suffix.
		 */
    private String suffix;

    public String getPrefix() {
        return this.prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSuffix() {
        return this.suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }

}

В классе WebMvcProperties есть такой внутренний класс.Внутренний класс имеет две переменные-члены, префикс и суффикс, которые используются для установки префикса и суффикса представления соответственно, поэтому, если мы хотим его настроить, нам нужно написать это в файле конфигурации. :

spring.mvc.view.prefix=/views/
spring.mvc.view.suffix=.html

Веб-разработка

Традиционная веб-разработка Spring требует написания большого количества конфигураций, но использование SpringBoot позволит избежать операции написания конфигурации и напрямую столкнуться с разработкой бизнес-логики.Давайте посмотрим, как использовать SpringBoot для веб-разработки!

Статическая обработка ресурсов

SpringBoot по умолчанию устанавливает несколько каталогов статических ресурсов:

  • /static
  • /public
  • /resources
  • /META-INF/resources

Эти каталоги должны быть установлены в пути к классам.Если это так, статические ресурсы, размещенные в этих каталогах, могут быть доступны напрямую.image.pngВы также можете установить префикс доступа к ресурсу через конфигурацию:

spring.mvc.static-path-pattern=/res/**

На данный момент, если вы хотите получить доступ к статическим ресурсам, вы должны добавить префикс RES.

Мы также можем изменить путь к ресурсу SpringBoot по умолчанию, просто добавим конфигурацию:

spring.web.resources.static-locations=classpath:/myImg

Если мы это сделаем, мы сможем поместить статические ресурсы только в каталог myImg, а все предыдущие каталоги статических ресурсов станут недействительными.

страница приветствия

SpringBoot предоставляет два способа реализации приветственной страницы: первый — разместить приветственную страницу в каталоге ресурсов:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>SpringBoot Index!</h1>
</body>
</html>

Результат посещения:image.pngВторой способ — обработать запрос /index через контроллер:

@Controller
public class HelloController {

    @RequestMapping("/")
    public String toIndex(){
        return "hello";
    }
}

Favicon

SpringBoot также предоставляет возможность автоматически установить значок веб-сайта, вам нужно только установить имяfavicon.icoКартинку можно поместить в каталог статических ресурсов:image.png

Сопоставление запросов на отдых

В SpringBoot HiddenHttpMethodFilter был зарегистрирован по умолчанию, поэтому вы можете напрямую писать URL-адреса в стиле Rest, просто добавьте в форму поле запроса атрибута _method:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/user" method="get">
        <input value="Get提交" type="submit">
    </form>
    <form action="/user" method="post">
        <input value="Post提交" type="submit">
    </form>
    <form action="/user" method="post">
        <input type="hidden" name="_method" value="DELETE">
        <input value="Delete提交" type="submit">
    </form>
    <form action="/user" method="post">
        <input type="hidden" name="_method" value="PUT">
        <input value="Put提交" type="submit">
    </form>
</body>
</html>

Напишите контроллер для обработки запроса:

@RestController
public class HelloController {

    @GetMapping("/user")
    public String getUser(){
        return "Get";
    }

    @PostMapping("/user")
    public String postUser(){
        return "Post";
    }

    @DeleteMapping("/user")
    public String deleteUser(){
        return "Delete";
    }

    @PutMapping("/user")
    public String putUser(){
        return "Put";
    }
}

Наконец, вам нужно включить поддержку Rest в файле конфигурации:

spring.mvc.hiddenmethod.filter.enabled=true

Общие параметры и примечания

Вот некоторые общие параметры и аннотации веб-разработки.

@PathVariable

Эта аннотация используется для получения переменных пути, таких как:

@GetMapping("/user/{id}")
public String getUser(@PathVariable("id") Integer id){
    return id + "";
}

На этом этапе, если URL-адрес запросаhttp://localhost:8080/user/2, то значение id получается равным 2.

@RequestHeader

Эта аннотация используется для получения заголовков запросов, таких как:

@GetMapping("/header")
public String getHeader(@RequestHeader("User-Agent") String userAgent){
    return userAgent;
}

Он также может получить всю информацию о заголовке запроса через коллекцию карт:

@GetMapping("/header")
public Map<String, String> getHeader(@RequestHeader Map<String,String> headers){
    return headers;
}

@RequestParam

Эта аннотация используется для получения параметров запроса, таких как:

@GetMapping("/param")
public String getParam(@RequestParam("name") String name,
                       @RequestParam("age") Integer age){
    return name + ":" + age;
}

На этом этапе, если URL-адрес запросаhttp://localhost:8080/param?name=zhangsan&age=20, то получите значениеzhangsan:20.

@CookieValue

Эта аннотация используется для получения значений файлов cookie, таких как:

@GetMapping("/cookie")
public String getCookie(@CookieValue("Idea-8296e76f") String cookie) {
    return cookie;
}

Он также может получить объект Cookie по имени ключа Cookie:

@GetMapping("/cookie")
public String getCookie(@CookieValue("Idea-8296e76f") Cookie cookie) {
    return cookie.getName();
}

@RequestBody

Эта аннотация используется для получения значения тела запроса, например:

@PostMapping("/body")
public String getBody(@RequestBody String content) {
    return content;
}

Поскольку нужно получить значение тела запроса, только запрос Post имеет тело запроса, поэтому напишите форму:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/body" method="post">
        账号:<input type="text" name="username">
        <br>
        密码:<input type="text" name="password">
        <br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

После отправки данных через эту форму я получаюusername=admin&password=123.

@RequestAttribute

Эта аннотация используется для получения данных поля запроса, таких как:

@GetMapping("/success")
public String success(@RequestAttribute("msg") String msg){
    return msg;
}

Данные в поле запроса можно получить по имени ключа.

@MatrixVariable

Эта аннотация используется для получения матричных переменных, таких как:

@GetMapping("/matrix/{path}")
public String getMatrix(@MatrixVariable("name") String name,
                        @MatrixVariable("age") Integer age,
                        @PathVariable("path") String path) {
    return path + "---" + name + ":" + age;
}

Для использования этой аннотации нам нужно обратить внимание на несколько моментов: во-первых, матричная переменная привязана к пути, поэтому отображение запроса должно содержать ${path}; Во-вторых, функция матричных переменных по умолчанию отключена в SpringBoot, поэтому нам также нужно включить эту функцию вручную:

@Configuration
public class MyConfig {

    @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {
            @Override
            public void configurePathMatch(PathMatchConfigurer configurer) {
                UrlPathHelper urlPathHelper = new UrlPathHelper();
                // 使矩阵变量生效
                urlPathHelper.setRemoveSemicolonContent(false);
                configurer.setUrlPathHelper(urlPathHelper);
            }
        };
    }
}

На этом этапе получите доступ к URL-адресу запроса:http://localhost:8080/matrix/test;name=zhangsan;age=20, получил ответ:test---zhangsan:20.

перехватчик

Идеальное веб-приложение должно учитывать вопросы безопасности. Например, только пользователи, которые входят в систему, могут просматривать ресурсы в системе или имеют только соответствующие разрешения для доступа к соответствующим ресурсам. Для этого нам нужно узнать о перехватчиках. может реализовать эти сертификаты безопасности.

Вот пример проверки входа:

/**
 * 登录检查
 */
public class LoginInterceptor implements HandlerInterceptor {

    /**
     * 目标方法执行前调用此方法
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 登录检查
        HttpSession session = request.getSession();
        // 检查Session中是否存放了登录用户的信息
        Object user = session.getAttribute("user");
        if(user != null){
            // 放行
            return true;
        }
        // 拦截,并跳转至登录页面
        response.sendRedirect("/toLogin");
        return false;
    }

    /**
     * 目标方法执行后调用此方法
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 页面渲染后调用此方法
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

После написания перехватчика его нужно настроить в контейнер:

@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加登录拦截器
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**") // 配置拦截哪些资源,/**会拦截所有资源,包括静态资源
                .excludePathPatterns("toLogin", "/css/**", "/js/**", "/fonts/**", "/images/**"); // 放行登录页面和静态资源
    }
}

Вам необходимо указать, какие ресурсы перехватчику необходимо перехватить, а какие ресурсы необходимо освободить, чтобы выполнить простую проверку входа.

Файл загружен

Как реализовать загрузку файлов в SpringBoot? Есть такая форма:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="f">
        <input type="submit" value="上传">
    </form>
</body>
</html>

Напишите метод управления:

@RestController
public class FileController {

    @PostMapping("/upload")
    public String upload(@RequestPart("f") MultipartFile file){
        String name = file.getOriginalFilename();
        long size = file.getSize();
        return name + ":" + size;
    }
}

Загруженный файл можно инкапсулировать в MultipartFile через аннотацию @RequestPart, и через этот объект можно получить всю информацию о файле. Выходной результат:image.pngПри загрузке нескольких файлов сначала измените информацию формы:

<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="f" multiple>
  <input type="submit" value="上传">
</form>

Добавьте множественный атрибут в поле файла, чтобы поддерживать загрузку нескольких файлов, а затем измените код контроллера:

@PostMapping("/upload")
public String upload(@RequestPart("f") MultipartFile[] file){
    return file.length + "";
}

Если вам нужно сохранить загруженный файл на сервер, вы можете сделать это:

@PostMapping("/upload")
public String upload(@RequestPart("f") MultipartFile[] file) throws IOException {
    for (MultipartFile multipartFile : file) {
        if(!multipartFile.isEmpty()){
            // 获取文件名
            String filename = multipartFile.getOriginalFilename();
            // 保存文件
            multipartFile.transferTo(new File("E:\\" + filename));
        }
    }
    return "success";
}

Поскольку размер загружаемого файла SpringBoot по умолчанию ограничен 1 МБ, если файл немного больше, загрузка не будет выполнена.С этой целью вы можете изменить конфигурацию SpringBoot по умолчанию:

spring.servlet.multipart.max-file-size=30MB	# 配置单个文件上传大小限制
spring.servlet.multipart.max-request-size=100MB	# 配置总文件上传大小限制

обработка ошибок

По умолчанию, если в приложении SpringBoot возникает исключение или ошибка, оно автоматически переходит на знакомую страницу /error:image.pngОднако, как правило, мы не выбираем отображение этой страницы при возникновении исключения, а хотим отображать собственную настроенную страницу.Для этого мы можем создать новый каталог ошибок в каталоге /static или /templates, а в /error Поместите страницы с именами 4xx и 5xx в каталог, и SpringBoot автоматически поможет нам их разрешить. В это время, когда возникает исключение 5xx, SpringBoot автоматически переходит на страницу 5xx.html.Конечно, вы также можете создать страницу, соответствующую каждому коду состояния, например, разместить 500.html, 501.html и 502. html файлы. , когда на сервере возникает соответствующее исключение, он переходит на соответствующую страницу.

доступ к данным

В этом узле мы рассмотрим интеграцию и использование SpringBoot и инфраструктуры уровня доступа к данным.

JDBC

Если мы хотим использовать собственный JDBC для разработки, SpringBoot уже настроил для нас информацию, связанную с JDBC, нам нужно только ввести зависимости:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.49</version>
</dependency>

SpringBoot автоматически настраивает источник данных HikariDataSource внизу, поэтому нам нужно указать только адрес, имя пользователя и пароль источника данных:

spring.datasource.url=jdbc:mysql:///springboot
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Поскольку SpringBoot автоматически настроил JdbcTemplate, мы можем использовать его напрямую:

@SpringBootTest
class SpringbootApplicationTests {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    void contextLoads() {
        List<String> names = jdbcTemplate.queryForList("select name from student",String.class);
        for (String name : names) {
            System.out.println(name);
        }
    }
}

Druid

Если вы не хотите использовать базовый источник данных SpringBoot, мы также можем изменить конфигурацию по умолчанию.На примере источника данных Druid сначала введите зависимости:

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid-spring-boot-starter</artifactId>
  <version>1.1.10</version>
</dependency>

И настроить Друид:

# 开启Druid的监控页功能
spring.datasource.druid.stat-view-servlet.enabled=true
# 开启防火墙功能
spring.datasource.druid.filter-class-names=stat,wall
# 配置监控页的用户名和密码
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=123
# 开启Druid的Web监控功能
spring.datasource.druid.web-stat-filter.enabled=true
# 配置监控哪些请求
spring.datasource.druid.web-stat-filter.url-pattern=/*

посетить в это времяhttp://localhost:8080/druid, перейдет на страницу мониторинга Друида:image.png

MyBatis

Далее мы интегрируем фреймворк MyBatis и представим его простое использование. Сначала введите зависимости:

<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>2.1.4</version>
</dependency>

Затем напишите интерфейс Mapper:

@Mapper
public interface StudentMapper {

    Student getStu(Integer id);
}

Запишите файл конфигурации Mappe:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wwj.springboot.dao.StudentMapper">
    <select id="getStu" resultType="com.wwj.springboot.bean.Student">
        select * from student where id = #{id}
    </select>
</mapper>

Наконец, настройте MyBatis:

# 配置Mapper配置文件的位置
mybatis.mapper-locations=classpath:mappers/*.xml
# 开启驼峰命名规则
mybatis.configuration.map-underscore-to-camel-case=true

Итак, вы можете использовать MyBatis:

@SpringBootTest
class SpringbootApplicationTests {

    @Autowired
    private StudentMapper studentMapper;

    @Test
    void contextLoads() {
        Student stu = studentMapper.getStu(1);
        System.out.println(stu);
    }
}

Redis

Если вы хотите интегрировать Redis, это тоже очень просто, сначала введите зависимости:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Затем настройте:

# 主机地址
spring.redis.host=172.16.136.196

Вам нужно только настроить адрес хоста Redis для работы с Redis.Этапы операции следующие:

@SpringBootTest
class SpringbootApplicationTests {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Test
    void contextLoads() {
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        operations.set("name","zhangsan");
        String name = operations.get("name");
        System.out.println(name);
    }
}

Если вы хотите использовать Jedis для работы с Redis, вам необходимо импортировать зависимости Jedis:

<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
</dependency>

и настроить:

spring.redis.client-type=jedis