栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot学习笔记

SpringBoot学习笔记

文章目录
  • SpringBoot学习笔记
  • 自己对SpringBoot的理解
  • 1.父依赖
    • 1.1启动器 spring-boot-starter
    • 1.2默认的主启动类
    • 1.3@SpringBootApplication
    • 1.4@ComponentScan
    • 1.5@SpringBootConfiguration
    • 1.6@EnableAutoConfiguration
    • 1.7spring.factories
    • 1.8不简单的方法
    • 1.9SpringApplication
    • 1.2.0run方法流程分析
    • 1.2.1SpringBoot理解
  • 2.yaml配置
    • 2.1配置文件
    • 2.2yaml概述
    • 2.3yaml基础语法
    • 2.4yaml注入配置文件
    • 2.5加载指定的配置文件
    • 2.6配置文件占位符
    • 2.7回顾properties配置
    • 对比小结
  • 3.JSR303数据校验及多环境切换
    • 3.1先看看如何使用
    • 3.2常见参数
    • 3.3多配置文件
    • 3.4yaml的多文档块
    • 3.5配置文件加载位置
    • 3.6拓展,运维小技巧
  • 4.SpringBoot Web开发
    • 4.1.jar:webapp!
    • 4. 2.模板引擎
    • 4.3引入Thymeleaf
  • 5.MVC配置原理
    • 5.1扩展SpringMvc
  • 6.员工管理系统
    • 6.1准备工作
    • 准备工作
    • 配置文件编写
    • 配置文件生效探究
    • 配置页面国际化值
    • 配置国际化解析
  • 7.Data
    • 创建测试项目测试数据源
    • JDBCTemplate
    • 测试
  • 8.Myabtis整合
    • 整合测试
    • 我们增加一个员工类再测试下,为之后做准备
  • 9.SpringSecurity(安全)
    • 安全简介
    • 实战测试
      • 实验环境搭建
      • 认识SpringSecurity
      • 认证和授权
      • 权限控制和注销
      • 记住我
      • 定制登录页
    • 完整配置代码
  • 10.Shiro
    • 1、Shiro简介
      • 【1】什么是Shiro?
      • 【2】Shiro 的特点
    • 2、核心组件
    • Shiro报错
  • 11.Shirio大整合
  • 12.Swagger
    • 1.导入依赖:
    • 2.配置Config 开启Swagger
    • 配置Swagger
    • Swagger配置扫描接口


自己对SpringBoot的理解

1.首先SpringBoot的@Configuration是让我们知道他是一个配置类,然后SpringBoot会有一个自动匹配注解,去识别我们现在的环境是什么,是普通java还是javaweb,随即去激活所相应的要使用的配置文件,以及配置类,再进行自动加载,在properties中,我们用什么,他就会去匹配什么并且进行自动加载,我们进行yaml配置文件进行配置的时候,其实都是在SpringBoot封装的文件里面,在AutoConfiguration和properties进行配置绑定,这样我们就可以使用自定义了。

我们之前写的HelloSpringBoot,到底是怎么运行的呢,Maven项目,我们一般从pom.xml文件探究起;


笔记基本上是复刻和原本的狂神笔记

1.父依赖

其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件!

    org.springframework.boot    spring-boot-starter-parent    2.2.5.RELEASE     

点进去,发现还有一个父依赖

    org.springframework.boot    spring-boot-dependencies    2.2.5.RELEASE    ../../spring-boot-dependencies

这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心;

以后我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了;

1.1启动器 spring-boot-starter
    org.springframework.boot    spring-boot-starter-web

springboot-boot-starter-xxx:就是spring-boot的场景启动器

spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件;

SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义 starter;

主启动类

分析完了 pom.xml 来看看这个启动类

1.2默认的主启动类
//@SpringBootApplication 来标注一个主程序类//说明这是一个Spring Boot应用@SpringBootApplicationpublic class SpringbootApplication {
   public static void main(String[] args) {     //以为是启动了一个方法,没想到启动了一个服务      SpringApplication.run(SpringbootApplication.class, args);   }
}

但是**一个简单的启动类并不简单!**我们来分析一下这些注解都干了什么

1.3@SpringBootApplication

作用:标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

进入这个注解:可以看到上面还有很多其他注解!

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

这个注解在Spring中很重要 ,它对应XML配置中的元素。

作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

1.5@SpringBootConfiguration

作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;

我们继续进去这个注解查看

// 点进去得到下面的 @Component@Configurationpublic @interface SpringBootConfiguration {}
@Componentpublic @interface Configuration {}

这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;

里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!

我们回到 SpringBootApplication 注解中继续看。

1.6@EnableAutoConfiguration

@EnableAutoConfiguration :开启自动配置功能

以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

点进注解接续查看:

@AutoConfigurationPackage :自动配置包

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

@import :Spring底层注解@import , 给容器中导入一个组件

Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;

这个分析完了,退到上一步,继续看

@Import({AutoConfigurationImportSelector.class}) :给容器导入组件 ;

AutoConfigurationImportSelector :自动配置导入选择器,那么它会导入哪些组件的选择器呢?我们点击去这个类看源码:

1、这个类中有一个这样的方法

// 获得候选的配置protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {    //这里的getSpringFactoriesLoaderFactoryClass()方法    //返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration    List configurations = javaSpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");    return configurations;}

2、这个方法又调用了 SpringFactoriesLoader 类的静态方法!我们进入SpringFactoriesLoader类loadFactoryNames() 方法

public static List loadFactoryNames(Class factoryClass, @Nullable ClassLoader classLoader) {    String factoryClassName = factoryClass.getName();    //这里它又调用了 loadSpringFactories 方法    return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());}

3、我们继续点击查看 loadSpringFactories 方法

private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) {    //获得classLoader , 我们返回可以看到这里得到的就是EnableAutoConfiguration标注的类本身    MultiValueMap result = (MultiValueMap)cache.get(classLoader);    if (result != null) {        return result;    } else {        try {            //去获取一个资源 "META-INF/spring.factories"            Enumeration urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");            LinkedMultiValueMap result = new LinkedMultiValueMap();
            //将读取到的资源遍历,封装成为一个Properties            while(urls.hasMoreElements()) {                URL url = (URL)urls.nextElement();                UrlResource resource = new UrlResource(url);                Properties properties = PropertiesLoaderUtils.loadProperties(resource);                Iterator var6 = properties.entrySet().iterator();
                while(var6.hasNext()) {                    Entry entry = (Entry)var6.next();                    String factoryClassName = ((String)entry.getKey()).trim();                    String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());                    int var10 = var9.length;
                    for(int var11 = 0; var11 < var10; ++var11) {                        String factoryName = var9[var11];                        result.add(factoryClassName, factoryName.trim());                    }                }            }
            cache.put(classLoader, result);            return result;        } catch (IOException var13) {            throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);        }    }}

4、发现一个多次出现的文件:spring.factories,全局搜索它

1.7spring.factories

我们根据源头打开spring.factories , 看到了很多自动配置的文件;这就是自动配置根源所在!

WebMvcAutoConfiguration

我们在上面的自动配置类随便找一个打开看看,比如 :WebMvcAutoConfiguration

可以看到这些一个个的都是JavaConfig配置类,而且都注入了一些Bean,可以找一些自己认识的类,看着熟悉一下!

所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。

结论:

  1. SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
  2. 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
  3. 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;
  4. 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
  5. 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;

现在大家应该大概的了解了下,SpringBoot的运行原理,后面我们还会深化一次!

SpringApplication

1.8不简单的方法

我最初以为就是运行了一个main方法,没想到却开启了一个服务;

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

SpringApplication.run分析

分析该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;

1.9SpringApplication

这个类主要做了以下四件事情:

1、推断应用的类型是普通的项目还是Web项目

2、查找并加载所有可用初始化器 , 设置到initializers属性中

3、找出所有的应用程序监听器,设置到listeners属性中

4、推断并设置main方法的定义类,找到运行的主类

查看构造器:

public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {    // ......    this.webApplicationType = WebApplicationType.deduceFromClasspath();    this.setInitializers(this.getSpringFactoriesInstances();    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));    this.mainApplicationClass = this.deduceMainApplicationClass();}
1.2.0run方法流程分析

跟着源码和这幅图就可以一探究竟了!

1.2.1SpringBoot理解
  • 自动装配
  • run()

全面接管SpringMVC的配置!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q5HrVyEC-1652436064033)(C:Users一字先生AppDataRoamingTyporatypora-user-imagesimage-20220328202504692.png)]

如果不配置使用了这个注解就会爆红,去官网拿个dependency


    org.springframework.boot
    spring-boot-configuration-processor
    true

或者使用javaconfig绑定配置文件的值

//加载指定的配置文件
@PropertySource(value="classpath:xxx.properties")
//SPEL表达式取出配置文件的值
@Value("${xx}")
2.yaml配置 2.1配置文件

SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的

  • application.properties

    • 语法结构 :key=value
  • application.yml

    • 语法结构 :key:空格 value

**配置文件的作用 :**修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;

比如我们可以在配置文件中修改Tomcat 默认启动的端口号!测试一下!

server.port=8081
2.2yaml概述

YAML是 “YAML Ain’t a Markup Language” (YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)

这种语言以数据作为中心,而不是以标记语言为重点!

以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,我们来对比下yaml和xml

传统xml配置:

    8081

yaml配置:

server:  prot: 8080
2.3yaml基础语法

说明:语法要求严格!

1、空格不能省略

2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。

3、属性和值的大小写都是十分敏感的。

字面量:普通的值 [ 数字,布尔值,字符串 ]

字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;

k: v

注意:

  • “ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;

    比如 :name: “kuang n shen” 输出 :kuang 换行 shen

  • ‘’ 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出

    比如 :name: ‘kuang n shen’ 输出 :kuang n shen

对象、Map(键值对)

#对象、Map格式k:     v1:    v2:

在下一行来写对象的属性和值得关系,注意缩进;比如:

student:    name: qinjiang    age: 3

行内写法

student: {name: qinjiang,age: 3}

数组( List、set )

用 - 值表示数组中的一个元素,比如:

pets: - cat - dog - pig

行内写法

pets: [cat,dog,pig]

修改SpringBoot的默认端口号

配置文件中添加,端口号的参数,就可以切换端口;

server:  port: 8082

注入配置文件

yaml文件更强大的地方在于,他可以给我们的实体类直接注入匹配值!

2.4yaml注入配置文件

1、在springboot项目中的resources目录下新建一个文件 application.yml

2、编写一个实体类 Dog;

package com.kuang.springboot.pojo;
@Component  //注册bean到容器中public class Dog {    private String name;    private Integer age;        //有参无参构造、get、set方法、toString()方法  }

3、思考,我们原来是如何给bean注入属性值的!@Value,给狗狗类测试一下:

@Component //注册beanpublic class Dog {    @Value("阿黄")    private String name;    @Value("18")    private Integer age;}

4、在SpringBoot的测试类下注入狗狗输出一下;

@SpringBootTestclass DemoApplicationTests {
    @Autowired //将狗狗自动注入进来    Dog dog;
    @Test    public void contextLoads() {        System.out.println(dog); //打印看下狗狗对象    }
}

结果成功输出,@Value注入成功,这是我们原来的办法对吧。

5、我们在编写一个复杂一点的实体类:Person 类

@Component //注册bean到容器中public class Person {    private String name;    private Integer age;    private Boolean happy;    private Date birth;    private Map maps;    private List lists;    private Dog dog;        //有参无参构造、get、set方法、toString()方法  }
 

6、我们来使用yaml配置的方式进行注入,大家写的时候注意区别和优势,我们编写一个yaml配置!

person:  name: qinjiang  age: 3  happy: false  birth: 2000/01/01  maps: {k1: v1,k2: v2}  lists:   - code   - girl   - music  dog:    name: 旺财    age: 1

7、我们刚才已经把person这个对象的所有值都写好了,我们现在来注入到我们的类中!

@Component //注册bean@ConfigurationProperties(prefix = "person")public class Person {    private String name;    private Integer age;    private Boolean happy;    private Date birth;    private Map maps;    private List lists;    private Dog dog;}
 

8、IDEA 提示,springboot配置注解处理器没有找到,让我们看文档,我们可以查看文档,找到一个依赖!

  org.springframework.boot  spring-boot-configuration-processor  true

9、确认以上配置都OK之后,我们去测试类中测试一下:

@SpringBootTestclass DemoApplicationTests {
    @Autowired    Person person; //将person自动注入进来
    @Test    public void contextLoads() {        System.out.println(person); //打印person信息    }
}

结果:所有值全部注入成功!

yaml配置注入到实体类完全OK!

课堂测试:

1、将配置文件的key 值 和 属性的值设置为不一样,则结果输出为null,注入失败

2、在配置一个person2,然后将 @ConfigurationProperties(prefix = “person2”) 指向我们的person2;

2.5加载指定的配置文件

**@PropertySource :**加载指定的配置文件;

@configurationProperties:默认从全局配置文件中获取值;

1、我们去在resources目录下新建一个person.properties文件

name=kuangshen

2、然后在我们的代码中指定加载person.properties文件

@PropertySource(value = "classpath:person.properties")@Component //注册beanpublic class Person {
    @Value("${name}")    private String name;
    ......  }

3、再次输出测试一下:指定配置文件绑定成功!

2.6配置文件占位符

配置文件还可以编写占位符生成随机数

person:    name: qinjiang${random.uuid} # 随机uuid    age: ${random.int}  # 随机int    happy: false    birth: 2000/01/01    maps: {k1: v1,k2: v2}    lists:      - code      - girl      - music    dog:      name: ${person.hello:other}_旺财      age: 1
2.7回顾properties配置

我们上面采用的yaml方法都是最简单的方式,开发中最常用的;也是springboot所推荐的!那我们来唠唠其他的实现方式,道理都是相同的;写还是那样写;配置文件除了yml还有我们之前常用的properties , 我们没有讲,我们来唠唠!

【注意】properties配置文件在写中文的时候,会有乱码 , 我们需要去IDEA中设置编码格式为UTF-8;

settings–>FileEncodings 中配置;

测试步骤:

1、新建一个实体类User

@Component //注册beanpublic class User {    private String name;    private int age;    private String sex;}

2、编辑配置文件 user.properties

user1.name=kuangshenuser1.age=18user1.sex=男

3、我们在User类上使用@Value来进行注入!

@Component //注册bean@PropertySource(value = "classpath:user.properties")public class User {    //直接使用@value    @Value("${user.name}") //从配置文件中取值    private String name;    @Value("#{9*2}")  // #{SPEL} Spring表达式    private int age;    @Value("男")  // 字面量    private String sex;}

4、Springboot测试

@SpringBootTestclass DemoApplicationTests {
    @Autowired    User user;
    @Test    public void contextLoads() {        System.out.println(user);    }
}

结果正常输出:

对比小结

@Value这个使用起来并不友好!我们需要为每个属性单独注解赋值,比较麻烦;我们来看个功能对比图

1、@ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加

2、松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下

3、JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性

4、复杂类型封装,yml中可以封装对象 , 使用value就不支持

结论:

配置yml和配置properties都可以获取到值 , 强烈推荐 yml;

如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;

如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!

jsr303校验

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WSrPj9uI-1652436064036)(C:Users一字先生AppDataRoamingTyporatypora-user-imagesimage-20220328205806802.png)]

3.JSR303数据校验及多环境切换 3.1先看看如何使用

Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。我们这里来写个注解让我们的name只能支持Email格式;

@Component //注册bean@ConfigurationProperties(prefix = "person")@Validated  //数据校验public class Person {
    @Email(message="邮箱格式错误") //name必须是邮箱格式    private String name;}

运行结果 :default message [不是一个合法的电子邮件地址];

使用数据校验,可以保证数据的正确性;

3.2常见参数
@NotNull(message="名字不能为空")private String userName;@Max(value=120,message="年龄最大不能查过120")private int age;@Email(message="邮箱格式错误")private String email;
空检查@Null       验证对象是否为null@NotNull    验证对象是否不为null, 无法查检长度为0的字符串@NotBlank   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.@NotEmpty   检查约束元素是否为NULL或者是EMPTY.    Booelan检查@AssertTrue     验证 Boolean 对象是否为 true  @AssertFalse    验证 Boolean 对象是否为 false      长度检查@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  @Length(min=, max=) string is between min and max included.
日期检查@Past       验证 Date 和 Calendar 对象是否在当前时间之前  @Future     验证 Date 和 Calendar 对象是否在当前时间之后  @Pattern    验证 String 对象是否符合正则表达式的规则
.......等等除此以外,我们还可以自定义一些数据校验规则

多环境切换

profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;

3.3多配置文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;

例如:

application-test.properties 代表测试环境配置

application-dev.properties 代表开发环境配置

但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;

我们需要通过一个配置来选择需要激活的环境:

#比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试;#我们启动SpringBoot,就可以看到已经切换到dev下的配置了;spring.profiles.active=dev
3.4yaml的多文档块

和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件,更加方便了 !

server:  port: 8081#选择要激活那个环境块spring:  profiles:    active: prod
---server:  port: 8083spring:  profiles: dev #配置环境的名称

---
server:  port: 8084spring:  profiles: prod  #配置环境的名称

注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!

3.5配置文件加载位置

外部加载配置文件的方式十分多,我们选择最常用的即可,在开发的资源文件中进行配置!

官方外部配置文件说明参考文档

springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件:

优先级1:项目路径下的config文件夹配置文件优先级2:项目路径下配置文件优先级3:资源路径下的config文件夹配置文件优先级4:资源路径下配置文件

优先级由高到底,高优先级的配置会覆盖低优先级的配置;

SpringBoot会从这四个位置全部加载主配置文件;互补配置;

我们在最低级的配置文件中设置一个项目访问路径的配置来测试互补问题;

#配置项目的访问路径server.servlet.context-path=/kuang
3.6拓展,运维小技巧

指定位置加载配置文件

我们还可以通过spring.config.location来改变默认的配置文件位置

项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;这种情况,一般是后期运维做的多,相同配置,外部指定的配置文件优先级最高

java -jar spring-boot-config.jar --spring.config.location=F:/application.properties
4.SpringBoot Web开发 4.1.jar:webapp!

自动装配

springboot到底帮我们配置了什么?我们能不能修改?

能修改那些东西?能不能扩展

  • xxxxAutoConfiguration…向容器中自动配置组件
  • xxxxProperties:自动配置类,装配配置文件中自定义的一些内容!

要解决的问题:

  • 导入静态资源:
  • 首页
  • jsp,模板引擎Thymeleaf
  • 装配扩展SpringMVC
  • 增删改查
  • 拦截器
  • 国际化!

什么webjars?

webjars/github-com-jquery-jquery/3.4.1/jquery.js

总结:

  1. 在SpringBoot中,我们可以使用以下方式处理静态资源
    • webjars http://localhost:8080/webjars/github-com-jquery-jquery/3.4.1/jquery.js
    • public,static, @Autowired JdbcTemplate jdbcTemplate; //查询employee表中所有数据 //List 中的1个 Map 对应数据库的 1行数据 //Map 中的 key 对应数据库的字段名,value 对应数据库的字段值 @GetMapping("/list") public List> userList(){ String sql = "select * from employee"; List> maps = jdbcTemplate.queryForList(sql); return maps; } //新增一个用户 @GetMapping("/add") public String addUser(){ //插入语句,注意时间问题 String sql = "insert into employee(last_name, email,gender,department,birth)" +" values ('狂神说','24736743@qq.com',1,101,'"+ new Date().toLocaleString() +"')"; jdbcTemplate.update(sql); //查询 return "addOk"; } //修改用户信息 @GetMapping("/update/{id}") public String updateUser(@PathVariable("id") int id){ //插入语句 String sql = "update employee set last_name=?,email=? where id="+id; //数据 Object[] objects = new Object[2]; objects[0] = "秦疆"; objects[1] = "24736743@sina.com"; jdbcTemplate.update(sql,objects); //查询 return "updateOk"; } //删除用户 @GetMapping("/delete/{id}") public String delUser(@PathVariable("id") int id){ //插入语句 String sql = "delete from employee where id=?"; jdbcTemplate.update(sql,id); //查询 return "deleteOk"; } 8.Myabtis整合

      M:数据和业务

      C:交接

      V:HTML

      1. 导入包
      2. 配置文件
      3. mybatis配置
      4. 编写sql
      5. 业务层(service)调用dao层
      6. controller调用service层

      官方文档:http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/

      Maven仓库地址:https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter/2.1.1

      整合测试

      1、导入 MyBatis 所需要的依赖

          org.mybatis.spring.boot    mybatis-spring-boot-starter    2.1.1
      

      2、配置数据库连接信息(不变)

      spring:
        datasource:
          username: root
          password: 123456
          url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
          driver-class-name: com.mysql.cj.jdbc.Driver
          type: com.alibaba.druid.pool.DruidDataSource
      
            #Spring Boot 默认是不注入这些属性值的,需要自己绑定
          #druid 数据源专有配置
          initialSize: 5
          minIdle: 5
          maxActive: 20
          maxWait: 60000
          timeBetweenEvictionRunsMillis: 60000
          minEvictableIdleTimeMillis: 300000
          validationQuery: SELECT 1 FROM DUAL
          testWhileIdle: true
          testOnBorrow: false
          testOnReturn: false
          poolPreparedStatements: true
      
            #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
            #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
          #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
          filters: stat,wall,log4j
          maxPoolPreparedStatementPerConnectionSize: 20
          useGlobalDataSourceStat: true
          connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
      
      
      

      3、测试数据库是否连接成功!

      4、创建实体类,导入 Lombok!

      Department.java

      package com.kuang.pojo;
      import lombok.AllArgsConstructor;
      import lombok.Data;import lombok.NoArgsConstructor;
      @Data@NoArgsConstructor@AllArgsConstructorpublic class Department {
          private Integer id;  
          private String departmentName;
      }
      

      5、创建mapper目录以及对应的 Mapper 接口

      DepartmentMapper.java

      //@Mapper : 表示本类是一个 MyBatis 的 Mapper@Mapper@Repositorypublic interface DepartmentMapper {
          // 获取所有部门信息    List getDepartments();
          // 通过id获得部门    Department getDepartment(Integer id);
      }
      

      6、对应的Mapper映射文件

      DepartmentMapper.xml

      
      
                 select * from department;    
                  select e.id as eid,last_name,email,gender,birth,d.id as did,d.department_name as dname        from department d,employee e        where d.id = e.department    
                  insert into employee (last_name,email,gender,department,birth)        values (#{lastName},#{email},#{gender},#{department},#{birth});    
          
                 
             
         
         

      4、这个请求提交上来,我们还需要验证处理,怎么做呢?我们可以查看formLogin()方法的源码!我们配置接收登录的用户名和密码的参数!

      http.formLogin()
        .usernameParameter("username")
        .passwordParameter("password")
        .loginPage("/toLogin")
        .loginProcessingUrl("/login"); // 登陆表单提交请求
      

      5、在登录页增加记住我的多选框

       记住我
      

      6、后端验证处理!

      //定制记住我的参数!
      http.rememberMe().rememberMeParameter("remember");
      

      7、测试,OK

      完整配置代码
      package com.kuang.config;
      
      import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
      import org.springframework.security.config.annotation.web.builders.HttpSecurity;
      import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
      import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
      import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
      
      @EnableWebSecurity
      public class SecurityConfig extends WebSecurityConfigurerAdapter {
      
         //定制请求的授权规则
         @Override
         protected void configure(HttpSecurity http) throws Exception {
      
             http.authorizeRequests().antMatchers("/").permitAll()
            .antMatchers("/level1/**").hasRole("vip1")
            .antMatchers("/level2/**").hasRole("vip2")
            .antMatchers("/level3/**").hasRole("vip3");
      
      
             //开启自动配置的登录功能:如果没有权限,就会跳转到登录页面!
                 // /login 请求来到登录页
                 // /login?error 重定向到这里表示登录失败
             http.formLogin()
                .usernameParameter("username")
                .passwordParameter("password")
                .loginPage("/toLogin")
                .loginProcessingUrl("/login"); // 登陆表单提交请求
      
             //开启自动配置的注销的功能
                 // /logout 注销请求
                 // .logoutSuccessUrl("/"); 注销成功来到首页
      
             http.csrf().disable();//关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求
             http.logout().logoutSuccessUrl("/");
      
             //记住我
             http.rememberMe().rememberMeParameter("remember");
        }
      
         //定义认证规则
         @Override
         protected void configure(AuthenticationManagerBuilder auth) throws Exception {
             //在内存中定义,也可以在jdbc中去拿....
             //Spring security 5.0中新增了多种加密方式,也改变了密码的格式。
             //要想我们的项目还能够正常登陆,需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密
             //spring security 官方推荐的是使用bcrypt加密方式。
      
             auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                    .withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
                    .and()
                    .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                    .and()
                    .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2");
        }
      }
      
      10.Shiro 1、Shiro简介 【1】什么是Shiro?

      Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。

      【2】Shiro 的特点

      Shiro 是一个强大而灵活的开源安全框架,能够非常清晰的处理认证、授权、管理会话以及密码加密。如下是它所具有的特点:

      · 易于理解的 Java Security API;

      · 简单的身份认证(登录),支持多种数据源(LDAP,JDBC 等);

      · 对角色的简单的签权(访问控制),也支持细粒度的鉴权;

      · 支持一级缓存,以提升应用程序的性能;

      · 内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境;

      · 异构客户端会话访问;

      · 非常简单的加密 API;

      · 不跟任何的框架或者容器捆绑,可以独立运行。

      2、核心组件

      Shiro架构图

      ·Subject

      Subject主体,外部应用与subject进行交互,subject将用户作为当前操作的主体,这个主体:可以是一个通过浏览器请求的用户,也可能是一个运行的程序。Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权。

      ·SecurityManager

      SecurityManager权限管理器,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口。

      ·Authenticator

      Authenticator即认证器,对用户登录时进行身份认证

      ·Authorizer

      Authorizer授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。

      ·Realm(数据库读取+认证功能+授权功能实现)

      Realm领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据

      比如:

      如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。

      注意:

      不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码。

      ·SessionManager

      SessionManager会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。

      ·SessionDAO

      SessionDAO即会话dao,是对session会话操作的一套接口

      比如:

      可以通过jdbc将会话存储到数据库;也可以把session存储到缓存服务器。

      ·CacheManager

      CacheManager缓存管理,将用户权限数据存储在缓存,这样可以提高性能。

      ·Cryptography

      Cryptography密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。

      
        org.apache.shiro
        shiro-web
        1.9.0
      
      

      去自己的gitee上面拿下来shiro

      然后进入[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tlXIEwkE-1652436064048)(C:Users一字先生AppDataRoamingTyporatypora-user-imagesimage-20220330184026380.png)]

      找到pom.xml导入maven依赖,也可以去官网看十分钟入门教程,但是官网进的太慢了!

      https://shiro.apache.org/10-minute-tutorial.html

         
              
                  org.apache.shiro
                  shiro-core
                  1.9.0
              
      
              
              
                  org.slf4j
                  jcl-over-slf4j
                  1.5.6
              
              
                  org.apache.logging.log4j
                  log4j-slf4j-impl
                  2.17.1
              
              
                  org.apache.logging.log4j
                  log4j-core
                  2.17.1
              
          
      

      1.导入依赖

      2.导入配置

      log4j.rootLogger=INFo,stdout
      
      log4j.appender.stdout=org.apache.log4j.consoleAppender
      log4j.appender.stdout.1ayout=org.apache.log4j.PatternLayout
      log4j.appender.stdout.layout.ConversionPattern=%d %p 【%c 】 - ‰m %n
      
      #General Apache libraries
      log4j.logger.org.apache=WARN
      
      #Spring
      log4j.logger.org.springframework=WARN
      
      #Default Shiro Logging
      log4j.logger.org.apache.shiro=INFO
      
      #Disable verbose Logging
      log4j.logger.org.apache.shiro.util.ThreadContext=WARN
      log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
      

      3.hello

      Spring-Secutiry都有

              //获取当前的用户对象 subject
      Subject currentUser = SecurityUtils.getSubject();
              //通过当前用户拿到session
      Session session = currentUser.getSession();
      	    //判断当前的用户是否被认证
      currentUser.isAuthenticated()
                  //token 令牌
                  //识别主体为用户名
      currentUser.getPrincipal()
      			//等级
      currentUser.hasRole("schwartz"))
              //粗粒度
      currentUser.isPermitted("winnebago:drive:eagle5")
      currentUser.logout()
      

      SpringBoot集成

      用户==> 管理所有用户 ==>连接数据

      整合导入:二选一

              
                  org.apache.shiro
                  shiro-spring-boot-web-starter
                  1.9.0
              
              
                  org.apache.shiro
                  shiro-spring
                  1.9.0
              
      
      Shiro报错

      1.首先:在建立Shiro三个板块时,每个板块都需要用bean注入名字,不然SpringBoot识别不到,

      2.先建立Reaml,因为上面的层次结构都是基于他来建立的

      3.在设置权限时,如果是所有人都需要访问的,则不需要进行登记设置,会报错

      4.如果配置没有问题,报错了,那么肯定是你的函数里面有内容写错了,可能写的不是跟web相关的

      11.Shirio大整合

      SpringBoot + Spirng + Mybatis +Druid + Log4j + Mysql

      
       
      
              
                  mysql
                  mysql-connector-java
              
      
      
              
                  log4j
                  log4j
                  1.2.17
              
      
      
              
                  com.alibaba
                  druid
                  1.2.8
              
      
              
                  org.mybatis.spring.boot
                  mybatis-spring-boot-starter
                  2.2.2
              
      
              
                  com.github.theborakompanioni
                  thymeleaf-extras-shiro
                  2.1.0
              
      
      
      12.Swagger 1.导入依赖:
              
                  io.springfox
                  springfox-boot-starter
                  3.0.0
              
      

      此依赖不会导致SpirngBoot2.6以上版本不兼容Springfox 及Swagger

      2.配置Config 开启Swagger
      @Configuration
      @EnableWebMvc
      //@EnableSwagger2
      public class SwaggerConfig {
          //开启swagger
      }
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-utcEct1w-1652436064049)(C:Users一字先生AppDataRoamingTyporatypora-user-imagesimage-20220331105722029.png)]

      配置Swagger
        //配置了Swagger Docket的bean实例
        @Bean
        public Docket docket(){
            return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
        }
        //配置Swagger信息=apInfo
        private ApiInfo apiInfo(){
            //作者信息
            Contact contact = new Contact("一字先生","http://www.baidu.com","11355084@qq.com");
            return new ApiInfo("一字先生",
                    "Mr.One",
                    "1.0", "点勾勾点",
                    contact, "Apache 2.0",
                    "http://www.apache.org/licenses/LICENSE-2.0",
                    new ArrayList());
        }
      
      Swagger配置扫描接口

      Docket.select()

          @Bean
          public Docket docket(){
              return new Docket(DocumentationType.SWAGGER_2)
                      .apiInfo(apiInfo())
                      .select()
                      //配置要扫描接口的方式
                      //basePackage:扫描指定的包
                      //any():扫描全部
                      //none():都不扫描
                      //withClassAnnotation():扫描类上的注解 参数是一个注解的反射对象
                      //withMethodAnnotation():扫描方法上的注解
                      .apis(RequestHandlerSelectors.basePackage("com.study.controller"))
                      //.paths()过滤什么路劲
                      .paths(PathSelectors.ant("/study/**"))
                      .build();
          }
      

      配置是否启动Docket .enable(boolean) 但是不能再select下面去,因为是启动

      我只希望我的Swagger在生产环境下使用,在发布的时候不使用

      • 判断是不是生产环境 flag=false
      • 注入enable(flag)
        public Docket docket(Environment environment){
              //设置要显示的Swagger环境
              Profiles profiles =  Profiles.of("dev","test");
              //获取项目的环境:
              //通过environment.acceptsProfiles判断自己是否处在设定的环境中
              boolean flag = environment.acceptsProfiles(profiles);
      
              return new Docket(DocumentationType.SWAGGER_2)
                      .apiInfo(apiInfo())
                      .enable(flag)
                      .select()
                      .apis(RequestHandlerSelectors.basePackage("com.study.controller"))
      //                .paths(PathSelectors.ant("/study/**"))
                      .build();
          }
      

      转载请注明:文章转载自 www.mshxw.com
      我们一直用心在做
      关于我们 文章归档 网站地图 联系我们

      版权所有 (c)2021-2022 MSHXW.COM

      ICP备案号:晋ICP备2021003244-6号