SpringBoot
SpringBoot
1、创建 SpringBoot 项目
1.1、利用官网创建
进入
SpringBoot
官网 SpringBoot划到
Quickstart Your Project
如下图
在
Dependencies
处添加项目依赖 最后点击GENERATE
会自动下载压缩包, 包中即为创建好的SpringBoot
i项目
1.2、利用 IDEA 创建
一般开发都是在 IDEA 中创建
1.3、项目结构
略
pom.xml 中的一些信息
1 | <dependencies> |
更改端口号:
在 application.propertise
中
1 | # 更改项目端口号 |
更改启动页面
- 在
resource
下新建banner.txt
在里面导入自己想要的图案即可
2、SpringBoot 原理初步
自动配置:
pom.xml
SpingBoot-dependencies:
核心依赖在父工程中
1 | <parent> |
- 在写一些或者引入 SpringBoot 的一些依赖中不需要写版本号, 就是因为有这些版本仓库
启动器
1 | <dependency> |
启动器即为
SpringBoot
的启动场景比如
spring-boot-starter-web
其就会导入 web 依赖SpringBoot
会将所有的功能场景 都变为一个一个启动器需要使用什么功能 就只需要找到对应的启动器就可以了
主程序
1 |
|
@SpringBootApplication
标注这个类是一个 SpringBoot
的应用 获取启动类的所有配置
注解
```
@SpringBootConfiguration : SpringBoot 的配置@Configuration Spring 配置类 @Component 这说明也是一个 Spring 的组件
@EnableAutoConfiguration : 自动配置
@AutoConfigurationPackage 自动配置包 @Import({Registrar.class}) 导入选择器 包注册 @Import({AutoConfigurationImportSelector.class}) 自动配置导入选择
//获取所有的配置
protected ListgetCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) 1
2
3
4
5
6
7
8
9
获取候选的配置
```java
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.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;
}META-INF/spring.factories 自动配置的核心文件
1
2如果这里面的条件都满足 才会生效
结论:
SpringBoot
所有的自动配置 都是在启动的时候扫描并加载spring.factories
所有的自动配置类都在这里面, 但是不一定生效 要判断条件是否 成立 只要导入了对应的start
就有对应的启动器了 有了启动器,自动装配就会生效 即配置成功SpringBoot
在启动时 从类路径下/META-INF/spring.factories
获取指定的值- 将这些自动配置的类导入容器, 自动配置类就会生效 进行自动配置
- 以前需要自动配置的东西 现在
SpringBoot
帮用户去做了 - 整合 JavaEE 解决方案和自动配置的东西都在
spring-boot-autoconfigure:2.5.5
这个包下 - 它会把所有需要导入的组件, 以类名的方式返回, 这些组件就会被添加到容器
- 容器中也会存在非常多的
XXX AutoConfiguration
的文件 就是这些类给容器中导入了这个场景需要的所有组件; 并自动配置@Configuration, JavaConfig
- 有了自动配置类 免去了手动编写配置文件的工作
3、主启动类的运行
1 |
|
分析该方法主要分为两部分, 一部分是 SpringApplication
的实例化, 二是 run
方法的执行
3.1、SpringApplication
这个类主要做了以下四件事情:
- 推断应用的类型是普通项目还是
Web
项目 - 查找并加载所有的可初始化器 设置到
initializers
属性中 - 找出所有的应用程序监听器 设置到
listeners
属性中 - 推断并设置
main
方法的定义类 找到运行的主类
查看构造器
1 | public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) { |
4、SpringBoot 配置
官方不推荐使用 properties
文件 推荐使用 .yaml
文件
4.1、配置文件
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的
application.properties
- 语法结构 :key=value
application.yml
- 语法结构 :key:空格 value
配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
比如我们可以在配置文件中修改Tomcat 默认启动的端口号!测试一下!
1 | server: |
yaml
可以给实体类赋值
1 | //如果不配置使用了这个注解 就会提示报红 |
实体类
1 |
|
yaml 配置
1 | person: |
注意:
关于上面的报红, 不影响使用. 但是可以点击上面的 Open documentation
来打开帮助文档获取了依赖并添加到pom.xml
中
1 | <dependency> |
@ConfigurationPropertie 的作用
- 将配置文件中配置的每一个属性的值, 映射到这个组件中;
- 告诉
SpringBoot
将本类中的所有属性和配置文件中相关的配置进行绑定 - 参数
prefix = "person"
: 将配置文件中的person
下面的所有属性一 一对应 - 只有这个组件是容器中的组件, 才能使用容器提供的
@ConfigurationPropertie
功能
注: 在配置文件中使用 properties
会出现乱码 这里在 setting
里把字体编码设置为 UTF-8
使用 properties
进行配置 但是需要自己手动取出配置文件中的值
在 resources
下新建 Cu1.properties
1 | name=Cu1 |
实体类中
1 | @Component |
@ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加
松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性
复杂类型封装,yml中可以封装对象 , 使用value就不支持
结论:
配置yml和配置properties都可以获取到值 , 强烈推荐 yml;
如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;
如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!
4.2、JSR303数据校验
先看看如何使用
Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。我们这里来写个注解让我们的name只能支持Email格式;
1 | @Component //注册bean |
运行结果 :default message [不是一个合法的电子邮件地址];
使用数据校验,可以保证数据的正确性;
常见参数
1 |
|
4.3、多环境切换
profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;
4.3.1、配置文件
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;
例如:
application-test.properties 代表测试环境配置
application-dev.properties 代表开发环境配置
但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;
我们需要通过一个配置来选择需要激活的环境:
1 | #比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试; |
4.3.2、yaml的多文档块
和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件,更加方便了 !
1 | server: |
注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!
properties 文件优先级最低会导致配置覆盖
4.3.3、配置文件加载位置
外部加载配置文件的方式十分多,我们选择最常用的即可,在开发的资源文件中进行配置!
官方外部配置文件说明参考文档
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件:
1 | 优先级1:项目路径下的config文件夹配置文件 |
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件;互补配置;
我们在最低级的配置文件中设置一个项目访问路径的配置来测试互补问题;
4.3.4、拓展,运维小技巧
指定位置加载配置文件
我们还可以通过spring.config.location来改变默认的配置文件位置
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;这种情况,一般是后期运维做的多,相同配置,外部指定的配置文件优先级最高
1 | java -jar spring-boot-config.jar --spring.config.location=F:/application.properties |
4.4、自动装配原理深入
4.4.1、分析自动配置原理
我们以 HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;
1 | //表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件; |
一句话总结 :根据当前不同的条件判断,决定这个配置类是否生效!
一但这个配置类生效;这个配置类就会给容器中添加各种组件;
这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
配置文件能配置什么就可以参照某个功能对应的这个属性类
我们去配置文件里面试试前缀,看提示!
这就是自动装配的原理!
4.4.2、精髓
1、SpringBoot启动会加载大量的自动配置类
2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxxAutoConfigurartion:自动配置类;给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
4.4.3、了解:@Conditional
了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;
@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。
我们怎么知道哪些自动配置类生效?
我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;
1 | #开启springboot的调试类 |
Positive matches:(自动配置类启用的:正匹配)
Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)
Unconditional classes: (没有条件的类)
5、SpringBoot Web 开发
要解决的问题:
- 导入静态资源
- 首页
- jsp 模板引擎 Thymeleaf
- 装配和扩展 SpringMVC
- 增删改查
- 拦截器
- 国际化
5.1、静态资源导入
5.1.1、静态资源映射规则
首先,我们搭建一个普通的SpringBoot项目,回顾一下HelloWorld程序!
写请求非常简单,那我们要引入我们前端资源,我们项目中有许多的静态资源,比如css,js等文件,这个SpringBoot怎么处理呢?
如果我们是一个web应用,我们的main下会有一个webapp,我们以前都是将所有的页面导在这里面的,对吧!但是我们现在的pom呢,打包方式是为jar的方式,那么这种方式SpringBoot能不能来给我们写页面呢?当然是可以的,但是SpringBoot对于静态资源放置的位置,是有规定的!
我们先来聊聊这个静态资源映射规则:
SpringBoot中,SpringMVC的web配置都在 WebMvcAutoConfiguration 这个配置类里面;
我们可以去看看 WebMvcAutoConfigurationAdapter 中有很多配置方法;
有一个方法:addResourceHandlers 添加资源处理
1 |
|
读一下源代码:比如所有的 /webjars/**
, 都需要去 classpath:/META-INF/resources/webjars/
找对应的资源;
什么是webjars
Webjars
本质就是以jar包的方式引入我们的静态资源 , 我们以前要导入一个静态资源文件,直接导入即可。
使用 SpringBoot
需要使用 Webjars
,我们可以去搜索一下:
网站:https://www.webjars.org
要使用jQuery,我们只要要引入jQuery对应版本的pom依赖即可!
1 | <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.4.1</version></dependency> |
导入完毕,查看webjars目录结构,并访问Jquery.js文件!
访问:只要是静态资源,SpringBoot
就会去对应的路径寻找资源,我们这里访问:http://localhost:8080/webjars/jquery/3.4.1/jquery.js
5.1.2、第二种静态资源映射规则
项目中使用自己的静态资源该怎么导入;
我们去找 staticPathPattern
发现第二种映射规则 :/**
, 访问当前的项目任意资源,它会去找 resourceProperties
这个类,我们可以点进去看一下分析:
1 | // 进入方法public String[] getStaticLocations() { return this.staticLocations;}// 找到对应的值private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;// 找到路径private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" }; |
ResourceProperties
可以设置和我们静态资源有关的参数;这里面指向了它会去寻找资源的文件夹,即上面数组的内容。
所以得出结论,以下四个目录存放的静态资源可以被我们识别:
1 | "classpath:/META-INF/resources/""classpath:/resources/""classpath:/static/""classpath:/public/" |
我们可以在 resources
根目录下新建对应的文件夹,都可以存放我们的静态文件;
比如我们访问http://localhost:8080/1.js
, 他就会去这些文件夹中寻找对应的静态资源文件;
5.1.3、自定义静态资源路径
我们也可以自己通过配置文件来指定一下,哪些文件夹是需要我们放静态资源文件的,在 application.properties
中配置;
1 | spring.resources.static-locations=classpath:/coding/,classpath:/kuang/ |
一旦自己定义了静态文件夹的路径,原来的自动配置就都会失效了!
5.1.4、总结:
参考源码推测出, 如果使用了自定义的配置文件并指定其为静态资源文件目录 那么默认的静态资源目录就会失效
在利用
url
访问静态资源目录时 首先判断是不是访问/webjars/**
如果是, 就会将url
拼接到classpath:/META-INF/resources/webjars/
下的静态资源目录下; 否则就会直接去按照第二种静态资源目录的规则去寻找第二种静态资源目录的优先级
resources
>static(默认)
>public
5.2、首页和图标定制
5.2.1、首页处理
继续向下看源码! 可以看到一个欢迎页的映射, 就是我们的首页!
1 | WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) { WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping( new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(), // getWelcomePage 获得欢迎页 this.mvcProperties.getStaticPathPattern()); welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider)); return welcomePageHandlerMapping;} |
点进去继续看 getWelcomPage()
1 | private Optional<Resource> getWelcomePage() { |
对于设置欢迎页, 可以放在静态资源文件夹下的 index.html
文件将会被 /**
映射 一般都放在 resouces/static
文件夹下
比如访问 http://localhost:8080/
,就会找静态资源文件夹下的 index.html
新建一个index.html
,在我们上面的3个目录中任意一个;然后访问测试 http://localhost:8080/
看结果!
对于网站图标 如果使用的是 SpringBoot2.x
之后的版本 设置关闭默认图标就失效了
5.2.2、图标定制
后来在网上搜怎么自定义图标 找到了一篇博客 但是没有生效在这里将博客链接贴一下, 有兴趣可以去尝试一下,
这个并不重要 关于 SpringBoot2.x之后版本的自定义图标
5.3、模板引擎 Thymeleaf
5.3.1、模板引擎
前端交给我们的页面,是 html
页面。如果是我们以前开发,我们需要把他们转成 jsp
页面,jsp
好处就是当我们查出一些数据转发到 JSP
页面以后,我们可以用jsp轻松实现数据的显示,及交互等。
jsp
支持非常强大的功能,包括能写 Java
代码,但是呢,我们现在的这种情况,SpringBoot
这个项目首先是以 jar
的方式,不是 war
,像第二,我们用的还是嵌入式的 Tomcat
,所以呢,他现在默认是不支持jsp的。
那不支持 jsp
,如果我们直接用纯静态页面的方式,那给我们开发会带来非常大的麻烦,那怎么办呢?
SpringBoot 推荐你可以来使用模板引擎:
模板引擎,我们其实大家听到很多,其实jsp就是一个模板引擎,还有用的比较多的 freemarker
,包括SpringBoot
给我们推荐的 Thymeleaf
,模板引擎有非常多,但再多的模板引擎,他们的思想都是一样的,什么样一个思想呢我们来看一下这张图:
模板引擎的作用就是我们来写一个页面模板,比如有些值呢,是动态的,我们写一些表达式。而这些值,从哪来呢,就是我们在后台封装一些数据。然后把这个模板和这个数据交给我们模板引擎,模板引擎按照我们这个数据帮你把这表达式解析、填充到我们指定的位置,然后把这个数据最终生成一个我们想要的内容给我们写出去,这就是我们这个模板引擎,不管是jsp还是其他模板引擎,都是这个思想。只不过呢,就是说不同模板引擎之间,他们可能这个语法有点不一样。其他的我就不介绍了,我主要来介绍一下 SpringBoot
给我们推荐的 Thymeleaf
模板引擎,这模板引擎呢,是一个高级语言的模板引擎,他的这个语法更简单。而且呢,功能更强大。
5.3.2、引入Thymeleaf
怎么引入呢,对于springboot来说,什么事情不都是一个start的事情嘛,我们去在项目中引入一下。给大家三个网址:
导入 pom
依赖
1 | <!--thymeleaf--> |
5.3.4、Thymeleaf分析
前面呢,我们已经引入了 Thymeleaf
,那这个要怎么使用呢?
我们首先得按照 SpringBoot
的自动配置原理看一下我们这个Thymeleaf
的自动配置规则,在按照那个规则,我们进行使用。
我们去找一下 Thymeleaf
的自动配置类:ThymeleafProperties
1 |
|
可以在其中看到默认的前缀和后缀!
只需要把需要的 html
页面放在类路径下的 templates
下,thymeleaf
就可以代替我们自动渲染了。
使用 thymeleaf
什么都不需要配置,只需要将其放在指定的文件夹下即可!
5.3.5、测试
test.html
1 |
|
Controller
1 | //在 template 目录下的所有页面 只能通过 Controller 来跳转 |
5.3.6、Thymeleaf 语法
学习语法, 最好是参考官方文档: Thymeleaf 官网
- 修改测试请求,增加数据传输;
1 |
|
要使用thymeleaf,需要在html文件中导入命名空间的约束,方便提示;
去官方文档的#3中看一下命名空间拿来过来:
1 | xmlns:th="http://www.thymeleaf.org" |
- 编写下前端页面
1 |
|
对于语法的深入
1. 可以使用任意的 th:attr 来替换Html中原生属性的值!
2. 能写哪些表达式
1 | Simple expressions:(表达式语法) |
测试 循环取出数组中内容
Controller
1 |
|
html
1 |
|
5.4、SpringMVC 配置
5.4.1、MVC自动配置原理
官网阅读
在进行项目编写前,还需要知道一个东西,就是 SpringBoot
对 SpringMVC
还做了哪些配置,包括如何扩展,如何定制.
只有把这些都搞清楚了,在之后使用才会更加得心应手. 途径一:源码分析,途径二:官方文档!地址
Spring MVC Auto-configuration
// Spring Boot为Spring MVC提供了自动配置,它可以很好地与大多数应用程序一起工作。
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
// 自动配置在Spring默认设置的基础上添加了以下功能:
The auto-configuration adds the following features on top of Spring’s defaults:
// 包含视图解析器
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
// 支持静态资源文件夹的路径,以及webjars
Support for serving static resources, including support for WebJars
// 自动注册了Converter:
// 转换器,这就是我们网页提交数据到后台自动封装成为对象的东西,比如把”1”字符串自动转换为int类型
// Formatter:【格式化器,比如页面给我们了一个2019-8-10,它会给我们自动格式化为Date对象】
Automatic registration of Converter, GenericConverter, and Formatter beans.
// HttpMessageConverters
// SpringMVC用来转换Http请求和响应的的,比如我们要把一个User对象转换为JSON字符串,可以去看官网文档解释;
Support for HttpMessageConverters (covered later in this document).
// 定义错误代码生成规则的
Automatic registration of MessageCodesResolver (covered later in this document).
// 首页定制
Static index.html support.
// 图标定制
Custom Favicon support (covered later in this document).
// 初始化数据绑定器:帮我们把请求数据绑定到JavaBean中!
Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document)./*
如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),则可以添加自己
的@configuration类,类型为webmvcconfiguer,但不得添加@EnableWebMvc。如果希望提供
RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义
实例,则可以声明WebMVCregistrationAdapter实例来提供此类组件。
*/
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration
(interceptors, formatters, view controllers, and other features), you can add your own
@Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide
custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or
ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.// 如果您想完全控制Spring MVC,可以添加自己的@Configuration,并用@EnableWebMvc进行注释。
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
仔细对照,看一下它怎么实现的,它告诉我们SpringBoot已经帮我们自动配置好了SpringMVC,然后自动配置了哪些东西呢?
ContentNegotiatingViewResolver 内容协商视图解析器
==注: 如果想要看更透彻的源码 需要降低 SpringBoot
的版本==
自动配置了 ViewResolver
,就是我们之前学习的 SpringMVC
的视图解析器;
即根据方法的返回值取得视图对象 (View)
,然后由视图对象决定如何渲染(转发, 重定向). 进入内部看这里的源码:可以找到 WebMvcAutoConfiguration
, 然后搜索 ContentNegotiatingViewResolver
。找到如下方法!
1 |
|
进入 resolver
类可以找到对应解析视图的代码
1 | // 注解说明:@Nullable 即参数可为null |
可以看到在 resolveViewName
方法中首先判断是否有用户自己定义的视图对象, 如果有就调用 getBestView
方法去调用getCandidateViews
得到 List<>
中获取的候选视图进行选择, 得到一个 bestView
继续点进去看 getCandidateViews
是怎么获得候选的视图的呢
getCandidateViews
中看到他是把所有的视图解析器拿来,进行 while
循环,挨个解析
1 | Iterator var5 = this.viewResolvers.iterator(); |
所以得出结论:ContentNegotiatingViewResolver 这个视图解析器就是用来组合所有的视图解析器的
再去研究下他的组合逻辑,看到有个属性viewResolvers,看看它是在哪里进行赋值的
1 | protected void initServletContext(ServletContext servletContext) { |
既然它是在容器中去找视图解析器,是否可以猜想,能够去实现一个视图解析器了呢?
可以手动给容器中去添加一个视图解析器;这个类就会帮我们自动的将它组合进来;下面即可以实现一下
- 在主程序中去写一个视图解析器来试试
1 |
|
这里更推荐将静态内部类拆分为一个独立的类 然后再单独写一个配置类用来返回自定义的配置类
- 怎么看自定义实现的视图解析器有没有起作用呢?
给 DispatcherServlet
中的 doDispatch
方法 加个断点进行调试一下,因为所有的请求都会走到这个方法中
- 启动项目,随后随便访问一个页面,看一下 Debug 信息, 找到
this
找到视图解析器,看到自定义的视图解析器的就在这里了;
转换器和格式化器
在 WebMvcAutoConfiguration
中找到格式化转换器:
1 |
|
点击进 format.getXXX()
中如果是新版本就会发现里面有默认属性但是具体是什么并不知道, 猜测是封装起来, 并通过 绑定配置文件在容器中进行初始化
如果是老版本就会有下面的代码
1 | public String getDateFormat() { |
可以看到在 Properties
或 yaml
文件中,可以自动配置它!
如果配置了自定义的格式化方式,就会注册到 Bean
中生效, 就可以在配置文件中配置日期格式化的规则:
1 | spring: |
1 | public void setDate(String date) { |
其余的就不一一举例, 可以自行去了解
修改SpringBoot的默认配置
这么多的自动配置,原理都是一样的,通过 WebMVC
的自动配置原理分析,需要学会一种学习方式,通过源码探究,得出结论;这个结论一定是属于自己的,而且一通百通。
SpringBoot
的底层,大量用到了这些设计细节思想,所以,需要多阅读源码! 得出结论;
SpringBoot
在自动配置很多组件的时候,先看容器中有没有用户自己配置的 (如果用户自己配置 @bean
),如果有就用用户配置的,如果没有就用自动配置的;
如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来!
扩展使用SpringMVC
官方文档如下:
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.
用户要做的就是编写一个 @Configuration
注解类,并且类型要为 WebMvcConfigurer
,并且不能标注@EnableWebMvc
注解;
下面去自定义一个;新建一个包叫config,写一个类 MyMvcConfig
;
1 | //全面扩展 springMVC |
测试请自行启动 SpringBoot
项目进行测试 最后发现自定义视图解析器中访问 /Cu1
后跳转到 test.html
所以说,要扩展SpringMVC,官方就推荐这么去使用,既保SpringBoot留所有的自动配置,也能使用用户扩展的配置!
可以去分析一下原理:
WebMvcAutoConfiguration
是SpringMVC
的自动配置类,里面有一个类WebMvcAutoConfigurationAdapter
这个类上有一个注解,在做其他自动配置时会导入:
@Import(EnableWebMvcConfiguration.class)
点进
EnableWebMvcConfiguration
这个类,它继承了一个父类:DelegatingWebMvcConfiguration
, 这个父类中有这样一段代码:1
2
3
4
5
6
7
8
9
10
11public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
// 从容器中获取所有的webmvcConfigurer
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
}可以在这个类中去寻找一个刚才设置的
viewController
当做参考,发现它调用了一个1
protected void addViewControllers(ViewControllerRegistry registry) { this.configurers.addViewControllers(registry);}
点击进入
addViewControllers
方法1
2
3
4
5
6
7
8public void addViewControllers(ViewControllerRegistry registry) {
Iterator var2 = this.delegates.iterator();
while (var2.hasNext()) {
// 将所有的WebMvcConfigurer相关配置来一起调用!包括我们自己配置的和Spring给我们配置的
WebMvcConfigurer delegate = (WebMvcConfigurer) var2.next();
delegate.addViewControllers(registry);
}
}所以得出结论:所有的WebMvcConfiguration都会被作用,不止Spring自己的配置类,用户自己的配置类当然也会被调用;
全面接管SpringMVC
官方文档:
If you want to take complete control of Spring MVC
you can add your own @Configuration annotated with @EnableWebMvc.
全面接管即:SpringBoot对SpringMVC
的自动配置不需要了,所有都是用户自己去配置!
只需在我们的配置类中要加一个 @EnableWebMvc
。
如果用户选择全面接管了 SpringMVC
了,那么之前 SpringBoot
默认配置的静态资源映射一定会无效,我们可以去测试一下;
当然,在开发中,不推荐使用全面接管SpringMVC
思考问题?为什么加了一个注解,自动配置就失效了!继续看下源码:
进入
@EnableWebMvc
发现它是导入了一个类,可以继续进去看1
public EnableWebMvc {}
进入
DelegatingWebMvcConfiguration
类 发现它继承了一个父类WebMvcConfigurationSupport
1
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { // ......}
现在来回顾一下Webmvc自动配置类
1
2
3
4
5
6
7
8
// 这个注解的意思就是:容器中没有这个组件的时候,这个自动配置类才生效
public class WebMvcAutoConfiguration { }总结一句话:
@EnableWebMvc
将WebMvcConfigurationSupport
组件导入进来了, 导致了 SpringMVC 的配置失效而导入的
WebMvcConfigurationSupport
只是SpringMVC
最基本的功能!==在SpringBoot中会有非常多的扩展配置,只要看见了这个,就应该多留心注意~==
6、数据库
6.1、SpringData简介
对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。
Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库,Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目。
数据库相关的启动器 :可以参考官方文档
6.2、整合JDBC (建议快速看过即可)
创建测试项目测试数据源
新建一个项目测试:springboot-data-jdbc ; 引入相应的模块!基础模块
编写yaml配置文件连接数据库;
1
2
3
4
5
6
7spring:
datasource:
username: root
password: 123456
#?serverTimezone=UTC解决时区的报错(如果不是 mysql 8.0+ 的话不需要设置时区)
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
配置完后,就可以直接去使用了,因为 SpringBoot
已经默认进行了自动配置
测试类测试
1 |
|
结果:可以看到默认配置的数据源为 : class com.zaxxer.hikari.HikariDataSource
, 并不需要手动配置
进行全局搜索, 找到数据源的所有自动配置都在: DataSourceAutoConfiguration
文件
1 |
|
可以使用 spring.datasource.type 指定自定义的数据源类型,值为 要使用的连接池实现的完全限定名。
SpringBoot
也提供了数据库连接的类 JDBCTemplate
JDBCTemplate
有了数据源
(com.zaxxer.hikari.HikariDataSource)
,可以拿到数据库连接(java.sql.Connection)
,有了连接,就可以使用原生的 JDBC 语句来操作数据库;即使不使用第三方第数据库操作框架,如
MyBatis
等,Spring
本身也对原生的JDBC
做了轻量级的封装,即JdbcTemplate
数据库操作的所有
CRUD
方法都在JdbcTemplate
中。Spring Boot
不仅提供了默认的数据源,同时默认已经配置好了JdbcTemplate
放在了容器中,用户只需自己注入即可使用JdbcTemplate
的自动配置是依赖org.springframework.boot.autoconfigure.jdbc
包下的JdbcTemplateConfiguration
类JdbcTemplate主要提供以下几类方法:
- execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
- update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
- query方法及queryForXXX方法:用于执行查询相关语句;
- call方法:用于执行存储过程、函数相关语句。
测试:
1 |
|
6.3、 集成Druid
Druid简介
Java
程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。
Druid
是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP
等 DB
池的优点,同时加入了日志监控。
Druid
监控 DB
池连接和 SQL
的执行情况,是针对监控而生的 DB
连接池。
Spring Boot 2.0
以上默认使用 Hikari
数据源,可以说 Hikari
与 Driud
都是当前Java Web
上最优秀的数据源,讲来重点介绍 Spring Boot
如何集成 Druid
数据源,实现数据库监控。Github地址
com.alibaba.druid.pool.DruidDataSource 基本配置参数如下:
配置数据源
1 | <!--druid 数据源--> |
切换数据源
Spring Boot 2.0
以上默认使用com.zaxxer.hikari.HikariDataSource
数据源,但可以 通过spring.datasource.type
指定数据源下面是
Druid
的配置可以设置数据源连接初始化大小、最大连接数、等待时间、最小连接数 等设置项;可以查看源码
1 | spring: |
导入Log4j 的依赖
1 | <!-- https://mvnrepository.com/artifact/log4j/log4j --> |
进行了上面的配置之后, 就不再使用 SprinhBoot
提供的默认 Druid
数据源了, 而是想要 SpringBoot
使用自定义配置的数据源, 需要自行利用配置类将数据源 DruidDataSource
组件添加到容器中并绑定属性
1 |
|
配置Druid数据源监控
Druid
数据源具有监控的功能,并提供了一个 web 界面方便用户查看,类似安装 路由器 时,同时也提供了一个默认的 web
页面。
所以第一步需要设置 Druid
的后台管理页面,比如 登录账号、密码 等;配置后台管理;
1 | //后台监控 相当于 web.xml |
配置完毕后,我们可以选择访问 :http://localhost:8080/druid/login.html
进入之后
配置 Druid web 监控 filter 过滤器
1 | //filter @Bean public FilterRegistrationBean webStarFilter() { FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>(); bean.setFilter(new WebStatFilter()); //可以过滤哪些请求 HashMap<String, String> initParameters = new HashMap<>(); //这些东西不进行统计 initParameters.put("exclusions", "*.js, *.css, /druid/*"); bean.setInitParameters(initParameters); return bean; } |
平时在工作中,按需求进行配置即可,主要用作监控!
完整代码
1 | @Configurationpublic |
6.4、整合 MyBatis
整合测试
1 | <!--mybatis 整合 mybatis-spring-boot-starter 非 SpringBoot 官方--> |
配置数据库连接信息(不变)
1 | # 47.100.227.175 |
测试数据库是否连接成功!
创建实体类,导入 Lombok
1 |
|
创建mapper目录以及对应的 Mapper 接口
1 | //这个注解表示了这是一个 MyBatis 的 Mapper 类 |
对应的Mapper映射文件
1 | <?xml version="1.0" encoding="UTF-8" ?> |
**然后设置 mapper.xml
的路径 **
1 | # 配置 MyBatis |
这样就把 .xml
配置文件加入到 MyBatis
中
如果不想配置可以选择在
中加入 MyBatis
扫描包的注解 但是建议把配置文件放到 resources
中统一配置
1 |
|
编写 Controller 进行测试!
1 |
|
7、SpringSecurity
安全简介
在 Web 开发中,安全一直是非常重要的一个方面。安全虽然属于应用的非功能性需求,但是应该在应用开发的初期就考虑进来。如果在应用开发的后期才考虑安全的问题,就可能陷入一个两难的境地:一方面,应用存在严重的安全漏洞,无法满足用户的要求,并可能造成用户的隐私数据被攻击者窃取;另一方面,应用的基本架构已经确定,要修复安全漏洞,可能需要对系统的架构做出比较重大的调整,因而需要更多的开发时间,影响应用的发布进程。因此,从应用开发的第一天就应该把安全相关的因素考虑进来,并在整个应用的开发过程中。
存在比较有名的:
Shiro
,Spring Security
!这里需要阐述一下的是,每一个框架的出现都是为了解决某一问题而产生了,那么
Spring Security
框架的出现是为了解决什么问题呢?
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirement
Spring Security
是一个功能强大且高度可定制的身份验证和访问控制框架。它实际上是保护基于 spring
的应用程序的标准。
Spring Security
是一个框架,侧重于为 Java
应用程序提供身份验证和授权。与所有 Spring
项目一样,Spring
安全性的真正强大之处在于它可以轻松地扩展以满足定制需求
从官网的介绍中可以知道这是一个 权限框架 想我们之前做项目是没有使用框架是怎么控制权限的?对于权限 一般会细分为 ==功能权限,访问权限,和菜单权限==。代码会写的非常的繁琐,冗余。
怎么解决之前写权限代码繁琐,冗余的问题,一些主流框架就应运而生而
Spring Scecurity
就是其中的一种。Spring 是一个非常流行和成功的 Java 应用开发框架。
Spring Security
基于Spring
框架,提供了一套 Web 应用安全性的完整解决方案。一般来说,Web 应用的安全性包括==用户认证====Authentication==)和==用户授权==(==Authorization==)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。对于上面提到的两种应用情景,
Spring Security
框架都有很好的支持。在用户认证方面,Spring Security
框架支持主流的认证方式,包括HTTP基本认证
、HTTP 表单验证
、HTTP 摘要认证
、OpenID
和LDAP
等。在用户授权方面,Spring Security
提供了基于角色的访问控制和访问控制列表(Access Control List
,ACL
),可以对应用中的领域对象进行细粒度的控制。
导入 SpringSecurity
pom.xml
1 | <dependencies> |
这里注意一下 thymeleaf
和 thymeleaf-extras-springsecurity
的版本号问题
认识SpringSecurity
- Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!
- 核心的几个类:
WebSecurityConfigurerAdapter
自定义Security策略
AuthenticationManagerBuilder
:自定义认证策略@EnableWebSecurity
:开启WebSecurity模式 【@Enablexxx开启某个功能】
Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。
“认证”(Authentication)
身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。
身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。
“授权” (Authorization)
授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。
这个概念是通用的,而不是只在Spring Security 中存在。
编写 Spring Security 配置类
1 | //AOP 拦截器 |
**下面将上面的代码拆分解释一下: **
1 |
|
@EnableWebSecurity
配合 继承 WebSecurityConfigurerAdapter
就可以达到开启 Spring Security
的自定义配置
部分自定义配置功能以重写 WebSecurityConfigurerAdapter
中的方法来实现
protected void configure(HttpSecurity http) throws Exception
用来配置用户访问 url 的权限1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24//授权
protected void configure(HttpSecurity http) throws Exception {
//首页所有人都可以访问 功能页只能有对应权限的人才能访问
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//没有权限会默认到登录界面 需要开启登录的页面
// .loginPage("") 定制登录页 参数为跳转登录页的请求
http.formLogin().loginPage("/toLogin").usernameParameter("username").passwordParameter("password").loginProcessingUrl("/login");
//关闭防攻击
http.csrf().disable();
//注销 开启了注销功能 跳到首页
http.logout().logoutSuccessUrl("/");
//开启 '记住我' 功能 cookie 默认保存两周
http.rememberMe().rememberMeParameter("remmeber");
}关于
loginProcessingUrl("/login")
1
http.formLogin().loginPage("/toLogin").usernameParameter("username").passwordParameter("password").loginProcessingUrl("/login");
loginProcessingUrl("/login")
表示登录页提交信息的时候是以“/login”
的URL
向Spring Security
并由登录界面<form th:action="@{/login}" method="post">
以 之前设定好的 URL 向后台提交数据来由Spring Security
实现的权限验证功能进行验证 但是在验证成功后有下面两种结果:- 通过主动点击登录 (指进入没有权限的页面导致跳转至登录界面) 进行登陆时, 点击登录并由后台验证通过后将自动回到 当前界面
- 进入没有权限的页面导致跳转至登录界面登录成功且权限符合当前页面的权限后会进入该页面
写完发现好像登录成功后不论之前进入的是有没有权限的页面 都会自动回到进入之前的页面….
protected void configure(AuthenticationManagerBuilder auth) throws Exception
记录合法的登录信息 用来在后台进行匹配1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//认证 SpringBoot 2.1.x 可以直接使用
//密码编码: PasswordEncoder
//在 Spring Security 5.0+ 新增了很多加密方法
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//从数据库中认证
//auth.jdbcAuthentication();
//从内存中认证
//这些数据正常应该在数据库读
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("Cu1").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");
}现在有一个需求: 用户没有登录的时候, 导航栏上只显示登录按钮, 用户登录之后, 导航栏可以显示登录的用户信息及注销按钮. 以及下面的功能: 比如
Cu1
这个用户, 其只有vip2
,vip3
功能, 那么登录则只显示这两个功能, 而vip1
的功能菜单不显示.实现上面的需求需要结合
thymeleaf
中的一些功能sec:authorize=”isAuthenticated()
:是否认证登录!来显示不同的页面1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37<div class="ui segment" id="index-header-nav" th:fragment="nav-menu">
<div class="ui secondary menu">
<a class="item" th:href="@{/index}">首页</a>
<!--登录注销-->
<div class="right menu">
<!--如果未登录-->
<!--<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i> 登录
</a>-->
<div sec:authorize="!isAuthenticated()">
<a class="item" th:href="@{/toLogin}">
<i class="sign-out icon"></i> 登录
</a>
</div>
<!--如果注销 用户名和注销按钮-->
<!-- <a class="item" th:href="@{/logout}">
<i class="sign-out icon"></i> 注销
</a>-->
<div sec:authorize="isAuthenticated()">
<a class="item">
用户名: <span sec:authentication="name"></span>
</a>
</div>
<div sec:authorize="isAuthenticated()">
<a class="item" th:href="@{/logout}">
<i class="sign-out icon"></i> 注销
</a>
</div>
</div>
</div>
</div>sec:authentication="name"
获取登录时用户名关于根据权限决定是否显示 这里只举一个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14<!--菜单根据用户的角色动态的实现-->
<div class="column" sec:authorize="hasRole('vip1')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 1</h5>
<hr>
<div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
<div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
<div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
</div>
</div>
</div>
</div>sec:authorize="hasRole('vip1')"
判断该用户是否有vip1
的权限==问题:==
如果现在依旧按照视频中的配置进行配置的话会发现
thymeleaf
提供的这个功能并没有生效视频中选择的是降低版本 这种行为我不提倡. 其实出现这个问题的原因在于
thymeleaf
和thymeleaf-extras-springsecurity
以及Spring Security
的版本不兼容出现的问题这里给出 thymeleaf 官方文档 和 一篇文章 可以去阅读一下 如果使用的是上面提供的
pom.xml
中的依赖应该是没有问题的
8、Shrio
提前了解一些什么
了解 Shiro
的三大对象
Subject
:当前用户(与当前应用交互的任何东西)—所有Subject
都绑定到SecurityManager
,与Subject
的所有交互都会委托给SecurityManager
;可以把Subject
认为是一个门面;SecurityManager
才是实际的执行者;SecurityManager
: 管理所有用户,负责与后边介绍的其他组件进行交互Realm
: 安全数据源用于认证和授权,Shiro
从Realm
获取安全数据(如用户、角色、权限),就是说SecurityManager
要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm
得到用户相应的角色 / 权限进行验证.
总结:Subject表示当前用户,Security Manager管理所有用户,负责用户与其他组件的交互(认证,授权,Session管理..),从Realm中获取数据.
SpringBoot 整合 Shrio
导入 Shrio
的包
1 | <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring --><dependency> |
配置 Shrio
的配置类
由上面的前置芝士可以发现 要使用 Shrio
就必须要有 Subject
, SecurityManager
, Realm
三层结构的配置所以在 SpringBoot
的配置包下需要有这些结构
由于 Reaml
层是没有默认实现的, 所以需要用户自己自定义的 所以需要用户自己去实现一个配置类
关于 UserRealm
(用于了登录时的 认证 和 授权) 配置类的自定义实现
1 | //自定义的 realm |
ShrioConfig
1 | 关于用户访问某个 url 时的拦截要求// |
1 | @Configuration |
由于 SpringBoot
为用户提供了默认实现的 SecurityManager
和 ShiroFilterFactoryBean
,所以不需要用户先提供自定义的类才能将其配置类放置进 SpringBoot
的容器中 PS( @Bean(name=“xxx”)
表示可以不使用 Spring
容器提供的默认名称, 而是指定 Spring
容器中的对象名称为 “xxx”
)
Shrio 整合 MyBatis
导入 MySQL
Druid
, MyBatis
的 pom
依赖
1 | <!--druid 数据源--> |
配置 MyBatis
配置文件
1 | spring: |
1 | # 配置 MyBatis |
**总结: ** 其实和之前整合数据库时没有什么区别
Shrio 整合 thymeleaf
导入 pom
依赖
1 | <!--shiro-thymeleaf 整合--> |
在 html
文件上加入命名空间
1 | <html lang="en" xmlns:th="http://www.thymeleaf.org" |
Shrio
与 thymeleaf
在 html
中的使用
1 |
|
Shrio
在 SpringBoot
中的使用
1 | @Controller |
扩展:
@qualifier 注解消除依赖注入冲突(当
SpringBoot
注入了相同的Bean/Componet
),可以指明我们要用哪个@primary 可以设置优先级
https://shiro.apache.org/java-authorization-guide.html 更多安全控制
thymeleaf
整合shiro
的标签guest
标签
shiro:guest
用户没有身份验证时显示相应信息,即游客访问信息。user
标签
shiro:user
用户已经身份验证/记住我登录后显示相应的信息。authenticated
标签
shiro:authenticated
用户已经身份验证通过,即Subject.login
登录成功,不是记住我登录的。notAuthenticated
标签
shiro:notAuthenticated
用户已经身份验证通过,即没有调用Subject.login
进行登录,包括记住我自动登录的也属于未进行身份验证。principal
标签
<shiro: principal/>
<shiro:principal property="username"/>
相当于
((User)Subject.getPrincipals()).getUsername()
。lacksPermission
标签
<shiro:lacksPermission name="org:create">
如果当前Subject
没有权限将显示body
体内容。hasRole
标签
<shiro:hasRole name="admin">
如果当前Subject
有角色将显示body
体内容。hasAnyRoles
标签
<shiro:hasAnyRoles name="admin,user">
如果当前Subject
有任意一个角色(或的关系)将显示body
体内容。lacksRole
标签
<shiro:lacksRole name="abc">
如果当前Subject
没有角色将显示body
体内容。hasPermission
标签
<shiro:hasPermission name="user:create">
如果当前Subject
有权限将显示body
体内容验证当前用户是否拥有指定权限
添加
9、Swagger
Swagger简介
前后端分离时代
前端:控制层和视图层
后端:控制层,数据访问层,服务层
特点:
前端调用 >— 后端的API接口
即:松耦合
产生的问题:
前端和后端工作人员之间的交互问题(武器的变多)
解决
Swagger的诞生!
Swagger是什么?
- 号称世界上最流行的API框架
- Restful Api 文档在线自动生成器 => API 文档 与API 定义同步更新
- 直接运行,在线测试API
- 支持多种语言 (如:Java,PHP等)
- 官网:https://swagger.io/
SpringBoot
整合 Swagger
导入 pom 依赖
编写 Swagger
配置类
1 |
|
测试类
1 |
|
常用注解
Swagger的所有注解定义在io.swagger.annotations包下
下面列一些经常用到的,未列举出来的可以另行查阅说明:
Swagger注解 | 说明 |
---|---|
@ApiModel(”说明这是什么类”) | 用于pojo下的实体类 |
@ApiModelProperty(value=”属性说明”,hidden=ture) | 用于实体类下的属性,hidden为true表示可以隐藏 |
@Api(“模块说明”) | 用于controller层继续模块说明 |
@ApiOperation(”方法说明”) | 用于controller层下的方法 |
@ApiParm(“参数说明”) | 用于controller层下的方法参数 |
希望 Swagger
在生产环境中使用 在发布后不能使用
- 判断是不是生产环境
flag = false
- 注入
enable(flag)
配置 API
文档分组
1 | .groupName("cu1") |
配置多个 API
文档 向 Spring
容器中配置多个 Docket
实例即可
总结:
可以通过
Swagger
给一些比较难理解的属性或者接口, 增加注释信息接口文档实时更新
可以在线测试
注意点 : 在正式发布时 关闭 Swagger
出于安全考虑 而且节省内存空间
扩展:皮肤!!
我们可以导入不同的包实现不同的皮肤定义:
1 | <!-- 引入swagger-ui-layer包 /docs.html--> |
- bootstrap-ui 访问 http://localhost:8080/doc.html
1 | <!-- 引入swagger-ui-layer包 /document.html--> |
- Layui-ui 访问 http://localhost:8080/docs.html
1 | <!-- 引入swagger-ui-layer包 /docs.html--> |
- mg-ui 访问 http://localhost:8080/document.html
1 | <!-- 引入swagger-ui-layer包 /document.html--> |
10、关于异步任务
请浏览 https://www.jianshu.com/p/20a4e37314fc
邮件发送
开启第一个
导入 pom 依赖
1 | <!--javax.mail: 配置--> |
调用 SpringBoot 的接口即可
1 |
|
定时任务
1 | TaskScheduler 任务调度者 |
使用
1 |
|
11、SpringBoot 整合 Redis
源码分析
1 |
|
整合测试
1、导入依赖
1 | <!--操作 redis--> |
2、配置连接
1 | #自动配置类都会绑定一个 properties 配置文件 RedisProperties |
3、测试
1 |
|
RedisTemplate 序列化配置
默认是使用 JDK
的序列化方式 但是可能需要使用 json
进行序列化 这时就需要自定义配置类
==关于对象的保存 如果没有序列化则会报错== 在企业中 所有的 pojo
类都会序列化
自定义 @Qualifier()
编写一个自定义的 RedisTemplate 如果出现多个 RedisTemplate
可以使用 @Qualifier()
来指定自定义的 @Qualifier()
在企业开发中 有 80%
的情况下都不会使用原生的方式去编写代码
1 |
|
RedisUtil 类
1 |
|