SpringBoot

SpringBoot

一、概述

1.Spring Boot是什么

Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架采用“习惯优于配置”的方式开发,可以快速构建Spring应用。

特性
能够创建独立的Spring应用
本身嵌入了Tomcat、Jetty容器
提供可选的starter依赖库简化应用构建配置
自动配置Spring以及第三方依赖
提供生产级的特性,如度量、检查和外部化配置
无代码生成并且不需要XML配置
2.使用SpringBoot的步骤:

1、创建一个SpringBoot应用,选择我们需要的模块,SpringBoot就会默认将我们的需要的模块自动配置好

2、手动在配置文件中配置部分配置项目就可以运行起来了

3、专注编写业务代码,不需要考虑以前那样一大堆的配置了。

3.Spring Boot目录结构

java Java源代码目录

resources 资源目录

resources/static 静态资源目录 ;js css images;

resources/templates 保存所有的模板页面; 展现层页面目录

resources/application.properties Spring Boot配置文件

test 单元测试目录

二、原理初探

1.pom.xml

spring-boot-dependencies 核心依赖在父工程中

在引入一些springboot依赖的时候,不需要指定版本,因为有这些版本仓库

spring-boot-starter springboot的依赖前缀

<!--  spingboot父依赖,里面包含springboot的默认依赖配置和插件配置-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
2.启动器
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

启动器:说白了就是springboot的启动场景

比如spring-boot-starter-web,就会导入web环境所有的依赖

springboot会将所有的功能场景,变成一个个的启动器

要使用什么功能,就找到对应的启动器即可

官方命名:

  • 前缀:spring-boot-starter-xxx
  • 比如:spring-boot-starter-web…

自定义命名:

  • xxx-spring-boot-starter
  • 比如:mybatis-spring-boot-starter
3.主程序
//程序主入口;标注这个类是一个springboot的应用
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        //将sringboot应用启动;SpringApplication
        SpringApplication.run(DemoApplication.class, args);
    }

}

@SpringBootApplication默认扫描启动类所在包及其子包,如果需要扫描其他路径,需要增加@ComponentScan或者@Import注解

注解
@SpringBootConfiguration  springboot的配置
	@Configuration  spring配置类
	@Component  
	
@EnableAutoConfiguration  自动配置
	@AutoConfigurationPackage  自动配置包
		@Import(AutoConfigurationPackages.Registrar.class):自动配置包注册
	@Import(AutoConfigurationImportSelector.class):自动配置导入选择

结论:

所有的自动配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里面,但不一定生效,要判断条件是否成立,只要导入了对应的start,就会有对应的启动器了,有了启动器,自动装配就会生效,然后就配置成功。

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

SpringApplication.run

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

SpringApplication

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

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

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

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

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

三、yaml语法

​ 以前的配置文件,大多数用xml来配置,比如一些简单的端口配置,我们来对比下yaml和xml还有properties的区别:

yaml配置端口:

server:
 	prot: 8080

xml配置:

<server>
	<prot>8080</prot>
</server>

properties配置:

server.prot=8080
存在的问题

xml‘文件’的形式,标签语言嵌套,层级深,解析麻烦。io操作,读取文件,解析效率低。

yml以缩进的方式代替层级的嵌套

1.配置文件

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

  • application.properties

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

    • 语法结构 :key:空格 value
1.1.配置文件的作用

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

1.2.常用配置

Spring Boot的配置文件是appication.properties,表格中列出了web相关的常用配置项。

debug false 开启/关闭调试模式

server.port 8080 服务器访问端口号

server.servlet.content-path / 应用上下文

spring.http.encoding.charset utf-8 默认字符集编码

spring.thymeleaf.cache 开启关闭页面缓存

spring.mvc.date-format 日期输入格式

spring.jackson.date-format json输出的日期格式

spring.jackson.time-zone 设置GMT时区

2.yaml概述

YAML是 “YAML Ain’t a Markup Language” 的递归缩写。

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

2.1.yaml基础语法

说明:语法要求严格!

1、空格不能省略

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

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

1)字面量:普通的值 [ 数字,布尔值,字符串 ]
k: v
2)对象、Map(键值对)
#对象、Map格式
k: 
    v1:
    v2:
3)数组( List、set )

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

pets:
 - cat
 - dog
 - pig
3.yaml注入配置文件

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

加载指定的配置文件

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

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

@ConfigurationProperties(prefix = “person”)

@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
4.JSR303数据校验

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

Springboot中可以用@validated来校验数据

5.多环境切换

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

多配置文件

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

例如:

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

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

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

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

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

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

配置文件加载位置

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

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

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

四、自动配置原理

自动配置就是SpringBoot在底层给我们自动做了一些配置,所以springboot项目不编写配置文件也可以正常运行,但是根据我们的具体开发需要修改SpringBoot自动配置的默认值;

//表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件;
@Configuration 
//启动指定类的ConfigurationProperties功能;  
//进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;  
//并把HttpProperties加入到ioc容器中  
@EnableConfigurationProperties({HttpProperties.class}) 
//Spring底层@Conditional注解  
//根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;  
//这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效  
@ConditionalOnWebApplication
//判断配置文件中是否存在某个配置
@ConditionalOnProperty

**总结 **:根据当前不同的条件判断,决定这个配置类是否生效!

  • 一但这个配置类生效;这个配置类就会给容器中添加各种组件;
  • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
  • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
  • 配置文件能配置什么就可以参照某个功能对应的这个属性类
精髓

1、SpringBoot启动会加载大量的自动配置类

2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)

4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

**xxxxAutoConfigurartion:自动配置类;**给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

4.2.@Conditional

自动配置类必须在一定的条件下才能生效;

@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

通过启用 debug=true属性;这样就可以知道哪些自动配置类生效;

五、整合

一、整合JDBC

1.创建测试项目,引入相应的模块!基础模块

2.项目建好之后,发现自动帮我们导入了如下的启动器:

<dependency>    
	<groupId>org.springframework.boot</groupId>    
	<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>    
<scope>runtime</scope></dependency>

3.编写yaml配置文件连接数据库;

spring:
  datasource:
    username: root    	
    password: root    	
    #?serverTimezone=UTC解决时区的报错    	
    url: jdbc:mysql://localhost:3306/mhk?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8    	
    driver-class-name: com.mysql.cj.jdbc.Driver

4.配置完这一些东西后,我们就可以直接去使用了,因为SpringBoot已经默认帮我们进行了自动配置;

DBCTemplate

1、有了数据源(com.zaxxer.hikari.HikariDataSource),然后可以拿到数据库连接(java.sql.Connection),有了连接,就可以使用原生的 JDBC 语句来操作数据库;

2、即使不使用第三方第数据库操作框架,如 MyBatis等,Spring 本身也对原生的JDBC 做了轻量级的封装,即JdbcTemplate。

3、数据库操作的所有 CRUD 方法都在 JdbcTemplate 中。

4、Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需自己注入即可使用

5、JdbcTemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的 JdbcTemplateConfiguration 类

JdbcTemplate主要提供以下几类方法:

  • execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
  • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
  • query方法及queryForXXX方法:用于执行查询相关语句;
  • call方法:用于执行存储过程、函数相关语句。
二、整合Druid

Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。

Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。

Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。

配置数据源

1、添加上 Druid 数据源依赖。

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
	<groupId>com.alibaba</groupId>    	
	<artifactId>druid</artifactId>	
	<version>1.1.21</version>
</dependency>

2、切换数据源;Spring Boot 2.0 以上默认使用 com.zaxxer.hikari.HikariDataSource 数据源,但可以通过 spring.datasource.type 指定数据源。

spring:
  datasource:  
    username: root    
    password: 123456    
    url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8    
    driver-class-name: com.mysql.cj.jdbc.Driver    
    type: com.alibaba.druid.pool.DruidDataSource 
    # 自定义数据源

3、数据源切换之后,在测试类中注入 DataSource

4、切换成功!设置数据源连接初始化大小、最大连接数、等待时间、最小连接数 等设置项;

三、整合MyBatis

1、导入 MyBatis 所需要的依赖

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

2、配置数据库连接信息

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

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

@Data
@NoArgsConstructor
@AllArgsConstructor

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

//@Mapper : 表示本类是一个 MyBatis 的 Mapper@Mapper

6、对应的Mapper映射文件

六、Web开发探究

SpringBoot中,SpringMVC的web配置都在 WebMvcAutoConfiguration 这个配置类里面;

1.静态资源处理

1.1.WebMvcAutoConfigurationAdapter 中有很多配置方法;

一、第一种映射规则

​ 有一个方法:addResourceHandlers 添加资源处理

​ 所有的 /webjars/** , 都需要去 classpath:/META-INF/resources/webjars/ 找对应的资源;

二、第二种映射规则

/** , 访问当前的项目任意资源,它会去找 resourceProperties 这个类

​ ResourceProperties 可以设置和我们静态资源有关的参数;这里面指向了它会去寻找资源的文件夹,即上面数组的内容。

所以得出结论,以下四个目录存放的静态资源可以被我们识别:

classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
1.webjars

Webjars本质就是以jar包的方式引入我们的静态资源 , 我们以前要导入一个静态资源文件,直接导入即可。

要使用jQuery,我们只要要引入jQuery对应版本的pom依赖即可!

<dependency>
	<groupId>org.webjars</groupId>    	
	<artifactId>jquery</artifactId>	
	<version>3.4.1</version>
</dependency>
三、自定义静态资源路径

我们也可以自己通过配置文件来指定一下,哪些文件夹是需要我们放静态资源文件的,在application.properties中配置;

spring.resources.static-locations=classpath:/coding/,classpath:/xinzhi/

一旦自己定义了静态文件夹的路径,原来的自动配置就都会失效了!

2.首页处理

欢迎页,静态资源文件夹下的所有 index.html 页面;被 /** 映射。

比如访问 http://localhost:8080/ ,就会找静态资源文件夹下的 index.html

Spring Boot在配置的静态内容位置中查找 favicon.ico。如果存在这样的文件,它将自动用作应用程序的favicon。

1、关闭SpringBoot默认图标

#关闭默认图标spring.mvc.favicon.enabled=false

2、放一个图标在静态资源目录下(放在 public 目录下)

3、清除浏览器缓存!刷新网页,发现图标已经变成自己的了!

3.Thymeleaf模板引擎

1.前端交给我们的页面,是html页面。如果是我们以前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。

SpringBoot现在默认是不支持jsp的;SpringBoot给我们推荐Thymeleaf

模板引擎的作用就是写一个页面模板,有些值是动态的,我们写一些表达式。而这些值,就是我们在后台封装一些数据。然后把这个模板和这个数据交给我们模板引擎,模板引擎按照我们这个数据帮你把这表达式解析、填充到我们指定的位置,然后把这个数据最终生成一个我们想要的内容给我们写出去,这就是我们这个模板引擎,不管是jsp还是其他模板引擎,都是这个思想。只不过,不同模板引擎之间,他们语法有点不一样。

3.2.引入Thymeleaf

找到对应的pom依赖

<!--thymeleaf-->
<dependency>
	<groupId>org.springframework.boot</groupId>    	
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
3.2.Thymeleaf分析

只需要把html页面放在类路径下的templates下,thymeleaf就可以帮我们自动渲染了。

使用thymeleaf什么都不需要配置,只需要将他放在指定的文件夹下即可!

 //默认的前缀和后缀!
  public static final String DEFAULT_PREFIX = "classpath:/templates/"; 
  public static final String DEFAULT_SUFFIX = ".html";
3.3.Thymeleaf 语法学习

使用任意的 th:attr 来替换Html中原生属性的值

七、MVC自动配置

编写一个@Configuration注解类,并且类型要为WebMvcConfigurer,还不能标注@EnableWebMvc注解(因为@EnableWebMvc将WebMvcConfigurationSupport组件导入进来了;)

1.ContentNegotiatingViewResolver 内容协商视图解析器

自动配置了ViewResolver,就是我们之前学习的SpringMVC的视图解析器;

即根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染(转发,重定向)。

这个视图解析器就是用来组合所有的视图解析器的

八、Swagger

  • 号称世界上最流行的API框架
  • Restful Api 文档在线自动生成器 => API 文档 与API 定义同步更新
  • 直接运行,在线测试API
  • 支持多种语言 (如:Java,PHP等)
  • 官网:https://swagger.io/
8.1.使用Swagger

1、新建一个SpringBoot-web项目

2、添加Maven依赖

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>    
    <artifactId>springfox-swagger2</artifactId>    
    <version>2.9.2</version>
</dependency>
    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
    <groupId>io.springfox</groupId>    
    <artifactId>springfox-swagger-ui</artifactId>    
    <version>2.9.2</version>
</dependency>

3、编写HelloController,测试确保运行成功!

4、要使用Swagger,我们需要编写一个配置类-SwaggerConfig来配置 Swagger

@Configuration 
//配置类@EnableSwagger2
// 开启Swagger2的自动配置
public class SwaggerConfig {  
}

5、访问测试 :http://localhost:8080/swagger-ui.html ,可以看到swagger的界面;

8.2.配置Swagger

1、Swagger实例Bean是Docket,所以通过配置Docket实例来配置Swaggger。

@Bean 
//配置docket以配置Swagger具体参数
public Docket docket() {
    return new Docket(DocumentationType.SWAGGER_2);
}

2、可以通过apiInfo()属性配置文档信息

//配置文档信息
private ApiInfo apiInfo() {
    Contact contact = new Contact("联系人名字", "http://xxx.xxx.com/联系人访问链接", "联系人邮箱");
    return new ApiInfo(            "Swagger学习", // 标题 
               "学习演示如何配置Swagger", // 描述           
                "v1.0", // 版本    
                "http://terms.service.url/组织链接", // 组织链接            
                contact, // 联系人信息            
                "Apach 2.0 许可", // 许可            
                "许可链接", // 许可连接           
                 new ArrayList<>()// 扩展    );}

3、Docket 实例关联上 apiInfo()

@Bean
public Docket docket() {
     return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
     }

4、重启项目,访问测试 http://localhost:8080/swagger-ui.html 看下效果;

8.3.配置扫描接口

1、构建Docket时通过select()方法配置怎么扫描接口。

@Bean
public Docket docket() {    
return new Docket(DocumentationType.SWAGGER_2)        
.apiInfo(apiInfo())        
.select()// 通过.select()方法,去配置扫描接口        		 //RequestHandlerSelectors配置如何扫描接口        
.apis(RequestHandlerSelectors.basePackage("com.xinzhi.swagger.controller"))        
.build();
}

2、重启项目测试,由于我们配置根据包的路径扫描接口,所以我们只能看到一个类

配置其他方式扫描接口
any() 
// 扫描所有,项目中的所有接口都会被扫描到
none() 
// 不扫描接口
// 通过方法上的注解扫描,如withMethodAnnotation(GetMapping.class)只扫描get请求
withMethodAnnotation(final Class<? extends Annotation> annotation)
// 通过类上的注解扫描,如.withClassAnnotation(Controller.class)只扫描有controller注解的类中的接口
withClassAnnotation(final Class<? extends Annotation> annotation)
basePackage(final String basePackage) // 根据包路径扫描接口
配置接口扫描过滤
// 配置如何通过path过滤,即这里只扫描请求以/xinzhi开头的接口      
.paths(PathSelectors.ant("/xinzhi/**"))
可选值
any() // 任何请求都扫描
none() // 任何请求都不扫描
regex(final String pathRegex) // 通过正则表达式控制
ant(final String antPattern) // 通过ant()控制
8.4.配置Swagger开关

1、通过enable()方法配置是否启用swagger,如果是false,swagger将不能在浏览器中访问了

@Bean
public Docket docket() {
   return new Docket(DocumentationType.SWAGGER_2)      
   .apiInfo(apiInfo())	  
   .enable(false)        //配置是否启用Swagger,如果是false,在浏览器将无法访问       
   ;
   }

2、如何动态配置当项目处于test、dev环境时显示swagger,处于prod时不显示?

@Bean
public Docket docket(Environment environment) {   
 // 设置要显示swagger的环境    
 Profiles of = Profiles.of("dev", "test");    
 // 判断当前是否处于该环境    
 // 通过 enable() 接收此参数判断是否要显示   
 boolean b = environment.acceptsProfiles(of);        
 return new Docket(DocumentationType.SWAGGER_2)    
     .apiInfo(apiInfo())        
     .enable(b) //配置是否启用Swagger,如果是false,在浏览器将无法访问        
     .select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口        
     .apis(RequestHandlerSelectors.basePackage("com.xinzhi.swagger.controller"))        
     // 配置如何通过path过滤,即这里只扫描请求以/xinzhi开头的接口        
     .paths(PathSelectors.ant("/xinzhi/**"))        
     .build();
     }

3、可以在项目中增加一个dev的配置文件查看效果!

8.5.配置API分组

1、如果没有配置分组,默认是default。通过groupName()方法即可配置分组:

@Bean
public Docket docket(Environment environment) {
    return new Docket(DocumentationType.SWAGGER_2)
    .apiInfo(apiInfo())        
    .groupName("hello")  // 配置分组       
     // 省略配置....
     }

2、重启项目查看分组

3、如何配置多个分组?配置多个分组只需要配置多个docket即可:

@Bean
public Docket docket1(){ 
   return new Docket(DocumentationType.SWAGGER_2).groupName("group1");
}
@Bean
public Docket docket2(){
   return new Docket(DocumentationType.SWAGGER_2).groupName("group2");
}
@Bean
public Docket docket3(){
    return new Docket(DocumentationType.SWAGGER_2).groupName("group3");
}

4、重启项目查看即可

8.6.实体配置

1、新建一个实体类

@ApiModel("用户实体")
public class User {
    @ApiModelProperty("用户名")
    public String username;    
    @ApiModelProperty("密码")    
    public String password;
 }

2、只要这个实体在请求接口的返回值上(即使是泛型),都能映射到实体项中:

@RequestMapping("/getUser")
public User getUser(){
    return new User();
 }

3、重启查看测试

8.7.常用注解

Swagger的所有注解定义在io.swagger.annotations包下

@ApiModel为类添加注释

@ApiModelProperty为类属性添加注释

Swagger注解简单说明
@Api(tags = “说明”)作用在模块类上
@ApiOperation(“说明”)作用在接口方法上
@ApiModel(“说明”)作用在类上
@ApiModelProperty(value = “说明”,hidden = true)作用在类方法和属性上,hidden设置为true可以隐藏该属性
@ApiParam(“说明”)作用在参数、方法和字段上,类似@ApiModelProperty

九、shiro、SpringSecurity

安全

一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

1.认识SpringSecurity

1.Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它实际上是保护基于spring的应用程序的标准。

2.Spring Security是一个框架,侧重于为Java应用程序提供身份验证和授权。与所有Spring项目一样,Spring安全性的真正强大之处在于它可以轻松地扩展以满足定制需求

3.Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!

记住几个类:

  • WebSecurityConfigurerAdapter:自定义Security策略
  • AuthenticationManagerBuilder:自定义认证策略
  • @EnableWebSecurity:开启WebSecurity模式

Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。

4.“认证”(Authentication)

身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。

身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。

  1. “授权” (Authorization)

授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。

这个概念是通用的,而不是只在Spring Security 中存在。

2.shiro
2.1.基本功能点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U5BHzP7x-1623306498195)(E:\桌面\mspringboot\image-20210509203242841.png)]

Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份;

Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的;

Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

Web Support:Web 支持,可以非常容易的集成到 Web 环境;

Caching:缓存,比如用户登录后,其用户信息、拥有的角色 / 权限不必每次去查,这样可以提高效率;

Concurrency:shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

Testing:提供测试支持;

Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

Remember Me:记住我

Shiro 不会去维护用户、维护权限;这些需要我们自己去设计 / 提供;然后通过相应的接口注入给 Shiro 即可。

2.2.Shiro的架构

Subject 用户

SecurityManager 管理所有用户

Realm 连接数据

也就是说

  1. 应用代码通过 Subject 来进行认证和授权,而 Subject 又委托给 SecurityManager;
  2. 我们需要给 Shiro 的 SecurityManager 注入 Realm,从而让 SecurityManager 能得到合法的用户及其权限进行判断。

​ 创建Realm 对象需要自定义类

​ entends AuthorizingRealm

Subject currentUser = SecurityUtils.getSubject();  //获得一个Subject对象
Session session = currentUser.getSession();   //拿到
sessioncurrentUser.isAuthenticated()  //判断用户是否认证
currentUser.getPrincipal()  //获取认证
currentUser.hasRole("schwartz")  //获取用户是否拥有某个角色
currentUser.isPermitted("lightsaber:wield")  //获取当前用户权限
currentUser.logout();   //注销
shiro内置过滤器

anon:无需认证可以访问

authc:认证了才能访问

user:必须拥有 记住我 功能才能用

perms:拥有某个资源的权限才能访问

role:拥有某个角色权限才能访问

十、异步、定时、邮件任务

异步任务

给方法添加@Async注解;

//告诉Spring这是一个异步方法@Async

SpringBoot就会自己开一个线程池,进行调用!但是要让这个注解生效,我们还需要在主程序上添加一个注解@EnableAsync ,开启异步注解功能;

@EnableAsync //开启异步注解功能
定时任务

Spring为我们提供了异步执行任务调度的方式,提供了两个接口。

  • TaskExecutor接口
  • TaskScheduler接口

两个注解:

  • @EnableScheduling
  • @Scheduled

一个方法,他需要定时执行

@Servicepublic class ScheduledService {
        //秒    分    时     日    月    周几    
        //0 * * * * MON-FRI    
        //注意cron表达式的用法;    
      @Scheduled(cron = "0 * * * * 0-7")    
      public void hello(){
           System.out.println("hello.....");
        }
      }

在主程序上增加@EnableScheduling 开启定时任务功能

十一、分布式

分布式理论
1.什么是分布式系统?

分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统

分布式系统(distributed system)是建立在网络之上的软件系统。

首先需要明确的是,只有当单个节点的处理能力无法满足日益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使用更好的CPU)高昂到得不偿失的时候,应用程序也不能进一步优化的时候,我们才需要考虑分布式系统。

RPC

RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。

也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

为什么要用RPC呢?

就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯,由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用。RPC就是要像调用本地的函数一样去调远程函数;

RPC两个核心模块:通讯,序列化。

Dubbo

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东西,说白了就是个远程服务调用的分布式框架

Dubbo 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

dubbo官网 http://dubbo.apache.org/zh-cn/index.html

1.dubbo基本概念

服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。

服务消费者(Consumer):调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者

监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

服务运行容器Container

2.调用关系说明

l 服务容器负责启动,加载,运行服务提供者。

l 服务提供者在启动时,向注册中心注册自己提供的服务。

l 服务消费者在启动时,向注册中心订阅自己所需的服务。

l 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

l 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

l 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

推荐使用Zookeeper 注册中心

3.

dubbo本身并不是一个服务软件。它其实就是一个jar包,能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务。

但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序dubbo-admin,不过这个监控即使不装也不影响使用。

4. Dubbo能做什么?

1.透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。

2.软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。

3.服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者

Zookeeper

1.Zookeeper 概念

Zookeeper 是一个分布式协调服务,可用于服务发现,分布式锁,分布式领导选举,配置管理等。

Zookeeper 提供了一个类似于 Linux 文件系统的树形结构(可认为是轻量级的内存文件系统,但 只适合存少量信息,完全不适合存储大量文件或者大文件),同时提供了对于每个节点的监控与 通知机制。

2.Zookeeper 角色

Zookeeper集群是一个基于主从复制的高可用集群,每个服务器承担如下三种角色中的一种

2.1. Leader

1.一个 Zookeeper 集群同一时间只会有一个实际工作的 Leader,它会发起并维护与各 Follwer 及Observer间的心跳。

2.所有的写操作必须要通过 Leader 完成再由 Leader 将写操作广播给其它服务器。只要有超过 半数节点(不包括observeer节点)写入成功,该写请求就会被提交(类 2PC 协议)。

2.2.Follower

1.一个Zookeeper集群可能同时存在多个Follower,它会响应Leader的心跳

2.Follower可直接处理并返回客户端的读请求,同时会将写请求转发给Leader处理

3.并且负责在Leader处理写请求时对请求进行投票。

2.3.Observer

角色与Follower类似,但是无投票权。

Zookeeper需保证高可用和强一致性,为了支持更多的客户端,需要增加更多 Server;Server 增多,投票阶段延迟增大,影响性能;引入 Observer, Observer不参与投票; Observers接受客户端的连接,并将写请求转发给leader节点; 加入更多Observer节点,提高伸缩性,同时不影响吞吐率。

clientPort=2181 zookeeper的默认端口号

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值