SpringBoot

打印 上一主题 下一主题

主题 551|帖子 551|积分 1653

SpringBoot2核心技术与响应式编程

SpringBoot2核心技术

SpringBoot2基础入门

Spring能做什么?



  • Spring的生态

    • 覆盖了:
      web开发
      数据访问
      安全控制
      分布式
      消息服务
      移动开发
      批处理
    • Spring5的重大升级



    • 内部源码设计

      • 基于Java8的一些新特性,如:接口默认实现。重新设计源码架构。


什么是SpringBoot?

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run"
能快速创建出生产级别的Spring应用
SpringBoot优点


  • Create stand-alone Spring applications


    • 创建独立Spring应用

  • Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)


    • 内嵌web服务器

  • Provide opinionated 'starter' dependencies to simplify your build configuration


    • 自动starter依赖,简化构建配置

  • Automatically configure Spring and 3rd party libraries whenever possible


    • 自动配置Spring以及第三方功能

  • Provide production-ready features such as metrics, health checks, and externalized configuration


    • 提供生产级别的监控、健康检查及外部化配置

  • Absolutely no code generation and no requirement for XML configuration


    • 无代码生成、无需编写XM

SpringBoot是整合Spring技术栈的一站式框架
SpringBoot是简化Spring技术栈的快速开发脚手架
SpringBoot缺点


  • 人称版本帝,迭代快,需要时刻关注变化
  • 封装太深,内部原理复杂,不容易精通
SpringBoot时代背景

微服务

James Lewis and Martin Fowler (2014)  提出微服务完整概念。https://martinfowler.com/microservices/
In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.-- James Lewis and Martin Fowler (2014)


  • 微服务是一种架构风格
  • 一个应用拆分为一组小型服务
  • 每个服务运行在自己的进程内,也就是可独立部署和升级
  • 服务之间使用轻量级HTTP交互
  • 服务围绕业务功能拆分
  • 可以由全自动部署机制独立部署
  • 去中心化,服务自治。服务可以使用不同的语言、不同的存储技术
分布式


  • 分布式的困难

    • 远程调用
    • 服务发现
    • 负载均衡
    • 服务容错
    • 配置管理
    • 服务监控
    • 链路追踪
    • 日志管理
    • 任务调度

分布式的解决

SpringBoot+SpringCloud

云原生

原生应用如何上云。 Cloud Native

  • 上云的困难

    • 服务自愈
    • 弹性伸缩
    • 服务隔离
    • 自动化部署
    • 灰度发布
    • 流量治理
    • ......

  • 上云的解决



如何学习SpringBoot

官方文档架构


查看版本新特性;
https://github.com/spring-projects/spring-boot/wiki#release-notes

快速体验SpringBoot

系统要求


  • Java 8 & 兼容java14 .
  • Maven 3.3+
  • idea 2019.1.2
Maven设置
  1. <mirrors>
  2.       <mirror>
  3.         <id>nexus-aliyun</id>
  4.         <mirrorOf>central</mirrorOf>
  5.         <name>Nexus aliyun</name>
  6.         <url>http://maven.aliyun.com/nexus/content/groups/public</url>
  7.       </mirror>
  8.   </mirrors>
  9.   <profiles>
  10.          <profile>
  11.               <id>jdk-1.8</id>
  12.               <activation>
  13.                 <activeByDefault>true</activeByDefault>
  14.                 <jdk>1.8</jdk>
  15.               </activation>
  16.               <properties>
  17.                 <maven.compiler.source>1.8</maven.compiler.source>
  18.                 <maven.compiler.target>1.8</maven.compiler.target>
  19.                 <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
  20.               </properties>
  21.          </profile>
  22.   </profiles>
复制代码
Hello Word

需求:浏览发送/hello请求,响应 Hello,Spring Boot 2
创建maven工程

引入依赖
  1. <parent>
  2.         <groupId>org.springframework.boot</groupId>
  3.         <artifactId>spring-boot-starter-parent</artifactId>
  4.         <version>2.3.4.RELEASE</version>
  5.     </parent>
  6.     <dependencies>
  7.         <dependency>
  8.             <groupId>org.springframework.boot</groupId>
  9.             <artifactId>spring-boot-starter-web</artifactId>
  10.         </dependency>
  11.     </dependencies>
复制代码
创建主程序
  1. package com.lkjedu.boot;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. /**
  5. * 主程序类
  6. * @SpringBootApplication:告诉SpringBoot这是一个SpringBoot应用
  7. *
  8. * */
  9. @SpringBootApplication
  10. public class MainApplication {
  11.     public static void main(String[] args) {
  12.         SpringApplication.run(MainApplication.class,arg s);
  13.     }
  14. }
复制代码
编写业务
  1. package com.lkjedu.boot.controller;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. @RestController
  5. public class HelloController {
  6.     @RequestMapping("hello")
  7.     public String handle01(){
  8.         return "Hello SpringBoot2";
  9.     }
  10. }
复制代码
测试

直接运行main方法
简化配置

简化部署
  1. <build>
  2.         <plugins>
  3.             <plugin>
  4.                 <groupId>org.springframework.boot</groupId>
  5.                 <artifactId>spring-boot-maven-plugin</artifactId>
  6.             </plugin>
  7.         </plugins>
  8.     </build>
复制代码
把项目打成jar包,直接在目标服务器执行即可。
注意点:

  • 取消掉cmd的快速编辑模式
依赖管理


  • 父项目做依赖管理
  1. 依赖管理   
  2. <parent>
  3.         <groupId>org.springframework.boot</groupId>
  4.         <artifactId>spring-boot-starter-parent</artifactId>
  5.         <version>2.3.4.RELEASE</version>
  6. </parent>
  7. 他的父项目
  8. <parent>
  9.     <groupId>org.springframework.boot</groupId>
  10.     <artifactId>spring-boot-dependencies</artifactId>
  11.     <version>2.3.4.RELEASE</version>
  12.   </parent>
  13. 几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
复制代码

  • 开发导入starter场景启动器
  1. 1、见到很多 spring-boot-starter-* : *就某种场景
  2. 2、只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
  3. 3、SpringBoot所有支持的场景
  4. https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
  5. 4、见到的  *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
  6. 5、所有场景启动器最底层的依赖
  7. <dependency>
  8.   <groupId>org.springframework.boot</groupId>
  9.   <artifactId>spring-boot-starter</artifactId>
  10.   <version>2.3.4.RELEASE</version>
  11.   <scope>compile</scope>
  12. </dependency>
复制代码

  • 无需关注版本号,自动版本仲裁
1、引入依赖默认都可以不写版本
2、引入非版本仲裁的jar,要写版本号。

  • 可以修改默认版本号
  1. 1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
  2. 2、在当前项目里面重写配置
  3.     <properties>
  4.         <mysql.version>5.1.43</mysql.version>
  5.     </properties>
复制代码
自动配置


  • 自动配好Tomcat


    • 引入Tomcat依赖。
    • 配置Tomcat

  1. <dependency>
  2.       <groupId>org.springframework.boot</groupId>
  3.       <artifactId>spring-boot-starter-tomcat</artifactId>
  4.       <version>2.3.4.RELEASE</version>
  5.       <scope>compile</scope>
  6.     </dependency>
复制代码

  • 自动配好SpringMVC


    • 引入SpringMVC全套组件
    • 自动配好SpringMVC常用组件(功能)

  • 自动配好Web常见功能,如:字符编码问题


    • SpringBoot帮我们配置好了所有web开发的常见场景

  • 默认的包结构


    • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
    • 无需以前的包扫描配置
    • 想要改变扫描路径,@SpringBootApplication(scanBasePackages="com.atguigu")





      • 或者@ComponentScan 指定扫描路径


  1. @SpringBootApplication
  2. 等同于
  3. @SpringBootConfiguration
  4. @EnableAutoConfiguration
  5. @ComponentScan("com.atguigu.boot")
复制代码

  • 各种配置拥有默认值


    • 默认配置最终都是映射到某个类上,如:MultipartProperties
    • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象

  • 按需加载所有自动配置项


    • 非常多的starter
    • 引入了哪些场景这个场景的自动配置才会开启
    • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面


  • ......
容器功能


  • 组件添加
1、@Configuration


  • 基本使用
  • Full模式与Lite模式


    • 示例
    • 最佳实战





      • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
      • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式


  1. #############################Configuration使用示例######################################################
  2. /**
  3. * 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
  4. * 2、配置类本身也是组件
  5. * 3、proxyBeanMethods:代理bean的方法
  6. *      Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
  7. *      Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
  8. *      组件依赖必须使用Full模式默认。其他默认是否Lite模式
  9. *
  10. *
  11. *
  12. */
  13. @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
  14. public class MyConfig {
  15.     /**
  16.      * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
  17.      * @return
  18.      */
  19.     @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
  20.     public User user01(){
  21.         User zhangsan = new User("zhangsan", 18);
  22.         //user组件依赖了Pet组件
  23.         zhangsan.setPet(tomcatPet());
  24.         return zhangsan;
  25.     }
  26.     @Bean("tom")
  27.     public Pet tomcatPet(){
  28.         return new Pet("tomcat");
  29.     }
  30. }
  31. ################################@Configuration测试代码如下########################################
  32. @SpringBootConfiguration
  33. @EnableAutoConfiguration
  34. @ComponentScan("com.atguigu.boot")
  35. public class MainApplication {
  36.     public static void main(String[] args) {
  37.         //1、返回我们IOC容器
  38.         ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
  39.         //2、查看容器里面的组件
  40.         String[] names = run.getBeanDefinitionNames();
  41.         for (String name : names) {
  42.             System.out.println(name);
  43.         }
  44.         //3、从容器中获取组件
  45.         Pet tom01 = run.getBean("tom", Pet.class);
  46.         Pet tom02 = run.getBean("tom", Pet.class);
  47.         System.out.println("组件:"+(tom01 == tom02));
  48.         //4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
  49.         MyConfig bean = run.getBean(MyConfig.class);
  50.         System.out.println(bean);
  51.         //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
  52.         //保持组件单实例
  53.         User user = bean.user01();
  54.         User user1 = bean.user01();
  55.         System.out.println(user == user1);
  56.         User user01 = run.getBean("user01", User.class);
  57.         Pet tom = run.getBean("tom", Pet.class);
  58.         System.out.println("用户的宠物:"+(user01.getPet() == tom));
  59.     }
  60. }
复制代码
2@Bean、@Component、@Controller、@Service、@Repository
  1. * 4、@Import({User.class, DBHelper.class})
  2. *      给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
  3. *
  4. *
  5. *
  6. */
  7. @Import({User.class, DBHelper.class})
  8. @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
  9. public class MyConfig {
  10. }
复制代码
@Import 高级用法: https://www.bilibili.com/video/BV1gW411W7wy?p=8
3、@ComponentScan、@Import
  1. * 4、@Import({User.class, DBHelper.class})
  2. *      给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
  3. *
  4. *
  5. *
  6. */
  7. @Import({User.class, DBHelper.class})
  8. @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
  9. public class MyConfig {
  10. }
复制代码
@Import 高级用法: https://www.bilibili.com/video/BV1gW411W7wy?p=8
4、@Conditional

条件装配:满足Conditional指定的条件,则进行组件注入
  1. =====================测试条件装配==========================
  2. @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
  3. //@ConditionalOnBean(name = "tom")
  4. @ConditionalOnMissingBean(name = "tom")
  5. public class MyConfig {
  6.     /**
  7.      * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
  8.      * @return
  9.      */
  10.     @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
  11.     public User user01(){
  12.         User zhangsan = new User("zhangsan", 18);
  13.         //user组件依赖了Pet组件
  14.         zhangsan.setPet(tomcatPet());
  15.         return zhangsan;
  16.     }
  17.     @Bean("tom22")
  18.     public Pet tomcatPet(){
  19.         return new Pet("tomcat");
  20.     }
  21. }
  22. public static void main(String[] args) {
  23.         //1、返回我们IOC容器
  24.         ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
  25.         //2、查看容器里面的组件
  26.         String[] names = run.getBeanDefinitionNames();
  27.         for (String name : names) {
  28.             System.out.println(name);
  29.         }
  30.         boolean tom = run.containsBean("tom");
  31.         System.out.println("容器中Tom组件:"+tom);
  32.         boolean user01 = run.containsBean("user01");
  33.         System.out.println("容器中user01组件:"+user01);
  34.         boolean tom22 = run.containsBean("tom22");
  35.         System.out.println("容器中tom22组件:"+tom22);
  36.     }
复制代码
2.2、原生配置文件引入


  • @ImportResource
    1. ======================beans.xml=========================
    2. <?xml version="1.0" encoding="UTF-8"?>
    3. <beans xmlns="http://www.springframework.org/schema/beans"
    4.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    5.        xmlns:context="http://www.springframework.org/schema/context"
    6.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    7.     <bean id="haha" >
    8.         <property name="name" value="zhangsan"></property>
    9.         <property name="age" value="18"></property>
    10.     </bean>
    11.     <bean id="hehe" >
    12.         <property name="name" value="tomcat"></property>
    13.     </bean>
    14. </beans>
    复制代码
    1. @ImportResource("classpath:beans.xml")
    2. public class MyConfig {}
    3. ======================测试=================
    4.         boolean haha = run.containsBean("haha");
    5.         boolean hehe = run.containsBean("hehe");
    6.         System.out.println("haha:"+haha);//true
    7.         System.out.println("hehe:"+hehe);//true
    复制代码

    • 配置绑定

@ConfigurationProperties

如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用;
  1. public class getProperties {
  2.      public static void main(String[] args) throws FileNotFoundException, IOException {
  3.          Properties pps = new Properties();
  4.          pps.load(new FileInputStream("a.properties"));
  5.          Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
  6.          while(enum1.hasMoreElements()) {
  7.              String strKey = (String) enum1.nextElement();
  8.              String strValue = pps.getProperty(strKey);
  9.              System.out.println(strKey + "=" + strValue);
  10.              //封装到JavaBean。
  11.          }
  12.      }
  13. }
复制代码

  • @Component + @ConfigurationProperties
  • @EnableConfigurationProperties + @ConfigurationProperties
    1. @EnableConfigurationProperties(Car.class)
    2. //1、开启Car配置绑定功能
    3. //2、把这个Car这个组件自动注册到容器中
    4. public class MyConfig {
    5. }
    复制代码
  1.    
  2. ##### 自动配置原理
  3. ###### 引导加载自动配置类
  4. ​~~~Java
  5. @SpringBootConfiguration
  6. @EnableAutoConfiguration
  7. @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  8.                 @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
  9. public @interface SpringBootApplication{}
  10. ======================
  11.    
复制代码
@SpringBootConfiguration

@Configuration:代表当前是一个配置类
@ComponentScan

指定我们扫描那些包
@EnableAutoConfiguration

启用 SpringBoot 的自动配置机制
  1. //也是两个注解的合成注解
  2. @AutoConfigurationPackage
  3. @Import({AutoConfigurationImportSelector.class})
  4. public @interface EnableAutoConfiguration {}
复制代码

  • @AutoConfigurationPackage:

    • 自动配置包
      1. @Import(AutoConfigurationPackages.Registrar.class)  //给容器中导入一个组件
      2. public @interface AutoConfigurationPackage {}
      3. //利用Registrar给容器中导入一系列组件
      4. //将指定的一个包下的所有组件导入进来?MainApplication 所在包下。
      复制代码

  • @Import(AutoConfigurationImportSelector.class)

      1. 1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
      2. 2、调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
      3. 3、利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件
      4. 4、从META-INF/spring.factories位置来加载一个文件。
      5.         默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
      6.     spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
      7.    
      复制代码


按需开启自动配置项
  1. 虽然我们127个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration
  2. 按照条件装配规则(@Conditional),最终会按需配置。
复制代码
修改默认配置
  1.         @Bean
  2.                 @ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
  3.                 @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
  4.                 public MultipartResolver multipartResolver(MultipartResolver resolver) {
  5.             //给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
  6.             //SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
  7.                         // Detect if the user has created a MultipartResolver but named it incorrectly
  8.                         return resolver;
  9.                 }
  10. 给容器中加入了文件上传解析器;
复制代码
SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先
  1. @Bean
  2.         @ConditionalOnMissingBean
  3.         public CharacterEncodingFilter characterEncodingFilter() {
  4.     }
复制代码
总结:
  1. ● SpringBoot先加载所有的自动配置类  xxxxxAutoConfiguration
  2. ● 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
  3. ● 生效的配置类就会给容器中装配很多组件
  4. ● 只要容器中有这些组件,相当于这些功能就有了
  5. ● 定制化配置
  6.   ○ 用户直接自己@Bean替换底层的组件
  7.   ○ 用户去看这个组件是获取的配置文件什么值就去修改。
  8. xxxxxAutoConfiguration ---> 组件  ---> xxxxProperties里面拿值  ----> application.properties
复制代码
最佳实践

开发小技巧

Lombok


  • import lombok.Data(@Data):生成已有属性的geter和seter方法
  • import lombok.ToString(@ToString):生成已有属性的toString方法
  • import lombok.NoArgsConstructor(@NoArgsConstructor):生成已有属性的无参构造器
  • import lombok.AllArgsConstructor(@AllArgsConstructor):生成已有属性的全参构造器
  • import lombok.EqualsAndHashCode(@EqualsAndHashCode):重写我们的Equals和HashCode方法
  • import lombok.slf4j(@slf4j):相当于我们的日志类
  1.         <dependency>
  2.             <groupId>org.projectlombok</groupId>
  3.             <artifactId>lombok</artifactId>
  4.         </dependency>
  5. idea中搜索安装lombok插件
复制代码
  1. ===============================简化JavaBean开发===================================
  2. @NoArgsConstructor
  3. //@AllArgsConstructor
  4. @Data
  5. @ToString
  6. @EqualsAndHashCode
  7. public class User {
  8.     private String name;
  9.     private Integer age;
  10.     private Pet pet;
  11.     public User(String name,Integer age){
  12.         this.name = name;
  13.         this.age = age;
  14.     }
  15. }
  16. ================================简化日志开发===================================
  17. @Slf4j
  18. @RestController
  19. public class HelloController {
  20.     @RequestMapping("/hello")
  21.     public String handle01(@RequestParam("name") String name){
  22.         
  23.         log.info("请求进来了....");
  24.         
  25.         return "Hello, Spring Boot 2!"+"你好:"+name;
  26.     }
  27. }
复制代码
dev-tools
  1.   <dependency>
  2.             <groupId>org.springframework.boot</groupId>
  3.             <artifactId>spring-boot-devtools</artifactId>
  4.             <optional>true</optional>
  5.         </dependency>
复制代码
项目或者页面修改以后:Ctrl+F9;
Spring Initailizr(项目初始化向导)


  • 选择我们需要的开发场景


    2.1、自动依赖引入
    ​       

    • 自动创建项目结构


      4.自动编写好主配置类
      ​       

    1、自动依赖引入


SpringBoot2核心功能

配置文件

文件类型

properties

同以前的properties用法
yaml


  • 简介

    • YAML 是 "YAML Ain't Markup Language"(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。非常适合用来做以数据为中心的配置文件

  • 基本语法

    • key: value;kv之间有空格
    • 大小写敏感
    • 使用缩进表示层级关系
    • 缩进不允许使用tab,只允许空格
    • 缩进的空格数不重要,只要相同层级的元素左对齐即可
    • '#'表示注释
    • 字符串无需加引号,如果要加,''与""表示字符串内容 会被 转义/不转义

  • 数据类型

    • 字面量:单个的、不可再分的值。date、boolean、string、number、null
      1. k: v
      复制代码
    • 对象:键值对的集合。map、hash、set、object
      1. 行内写法:  k: {k1:v1,k2:v2,k3:v3}
      2. #或
      3. k:
      4.         k1: v1
      5.   k2: v2
      6.   k3: v3
      复制代码
    • 数组:一组按次序排列的值。array、list、queue
      1. 行内写法:  k: [v1,v2,v3]
      2. #或者
      3. k:
      4. - v1
      5. - v2
      6. - v3
      复制代码
    • 提示:

      • 在yaml文件格里面式,单引号会将“\n”简单的字符串输出
      • 在yaml文件格里面式,双引号会将“\n”则会作为转义符


配置提示

自定义的类和配置文件绑定一般没有提示。
  1.                     org.springframework.boot            spring-boot-configuration-processor            true         <build>
  2.         <plugins>
  3.             <plugin>
  4.                 <groupId>org.springframework.boot</groupId>
  5.                 <artifactId>spring-boot-maven-plugin</artifactId>
  6.             </plugin>
  7.         </plugins>
  8.     </build>                                                                org.springframework.boot                            spring-boot-configuration-processor                                                                                    
复制代码
web开发

SpringMVC自动配置概览

Spring Boot provides auto-configuration for Spring MVC that works well with most applications.(大多场景我们都无需自定义配置)
The auto-configuration adds the following features on top of Spring’s defaults:

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.


    • 内容协商视图解析器和BeanName视图解析器

  • Support for serving static resources, including support for WebJars (covered later in this document)).


    • 静态资源(包括webjars)

  • Automatic registration of Converter, GenericConverter, and Formatter beans.


    • 自动注册 Converter,GenericConverter,Formatter

  • Support for HttpMessageConverters (covered later in this document).


    • 支持 HttpMessageConverters (后来我们配合内容协商理解原理)

  • Automatic registration of MessageCodesResolver (covered later in this document).


    • 自动注册 MessageCodesResolver (国际化用)

  • Static index.html support.


    • 静态index.html 页支持

  • Custom Favicon support (covered later in this document).


    • 自定义 Favicon

  • Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).


    • 自动使用 ConfigurableWebBindingInitializer ,(DataBinder负责将请求数据绑定到JavaBean上)

  • If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.
  • 不用@EnableWebMvc注解。使用 **@Configuration** + **WebMvcConfigurer** 自定义规则

  • If you want to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, and still keep the Spring Boot MVC customizations, you can declare a bean of type WebMvcRegistrations and use it to provide custom instances of those components.
  • 声明 **WebMvcRegistrations** 改变默认底层组件

  • If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc, or alternatively add your own @Configuration-annotated DelegatingWebMvcConfiguration as described in the Javadoc of @EnableWebMvc.
  • 使用 **@EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration 全面接管SpringMVC**
简单功能分析

静态资源访问


  • 静态资源目录
    只要静态资源放在类路径下: called /static (or /public or /resources or /META-INF/resources
    访问:当前项目根路径/+静态资源名
    原理:静态映射/**
    请求进来先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则直接报404
    改变默认的静态资源路径
    1. spring:
    2.   mvc:
    3.     static-path-pattern: /res/**
    4. #改变姿态资源路径
    5.   resources:
    6.     static-locations: [classpath:/haha/]
    复制代码
  • 静态资源访问前缀
    默认无前缀
    1. spring:
    2.   mvc:
    3.     static-path-pattern: /res/**
    复制代码
  • webjar
    自动映射 /webjars/**
    https://www.webjars.org/
    1.         <dependency>
    2.             <groupId>org.webjars</groupId>
    3.             <artifactId>jquery</artifactId>
    4.             <version>3.5.1</version>
    5.         </dependency>
    复制代码
    访问地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js   后面地址要按照依赖里面的包路径
欢迎页支持


  • 静态资源路径下  index.html


    • 可以配置静态资源路径
    • 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问

  1. spring:
  2. #  mvc:
  3. #    static-path-pattern: /res/**   这个会导致welcome page功能失效
  4.   resources:
  5.     static-locations: [classpath:/haha/]
复制代码
2.3、自定义 Favicon

favicon.ico 放在静态资源目录下即可。
  1. spring:
  2. #  mvc:
  3. #    static-path-pattern: /res/**   这个会导致 Favicon 功能失效
复制代码
静态资源配置原理


  • SpringBoot启动默认加载  xxxAutoConfiguration 类(自动配置类)
  • SpringMVC功能的自动配置类 WebMvcAutoConfiguration,生效
  1. @Configuration(proxyBeanMethods = false)
  2. @ConditionalOnWebApplication(type = Type.SERVLET)
  3. @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
  4. @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
  5. @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
  6. @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
  7.                 ValidationAutoConfiguration.class })
  8. public class WebMvcAutoConfiguration {}
复制代码

  • 给容器中配了什么。
  1.         @Configuration(proxyBeanMethods = false)
  2.         @Import(EnableWebMvcConfiguration.class)
  3.         @EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
  4.         @Order(0)
  5.         public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
复制代码

  • 配置文件的相关属性和xxx进行了绑定。WebMvcPropertiesspring.mvc、ResourcePropertiesspring.resources
配置类只有一个有参构造器
  1.         //有参构造器所有参数的值都会从容器中确定
  2. //ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象
  3. //WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
  4. //ListableBeanFactory beanFactory Spring的beanFactory
  5. //HttpMessageConverters 找到所有的HttpMessageConverters
  6. //ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。=========
  7. //DispatcherServletPath  
  8. //ServletRegistrationBean   给应用注册Servlet、Filter....
  9.         public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
  10.                                 ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
  11.                                 ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
  12.                                 ObjectProvider<DispatcherServletPath> dispatcherServletPath,
  13.                                 ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
  14.                         this.resourceProperties = resourceProperties;
  15.                         this.mvcProperties = mvcProperties;
  16.                         this.beanFactory = beanFactory;
  17.                         this.messageConvertersProvider = messageConvertersProvider;
  18.                         this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
  19.                         this.dispatcherServletPath = dispatcherServletPath;
  20.                         this.servletRegistrations = servletRegistrations;
  21.                 }
复制代码
配置 private Configuration configuration; mybatis.configuration下面的所有,就是相当于改mybatis全局配置文件中的值
  1. spring:
  2. #  mvc:
  3. #    static-path-pattern: /res/**
  4.   resources:
  5.     add-mappings: false   禁用所有静态资源规则
复制代码

  • 导入mybatis官方starter
  • 编写mapper接口。标准@Mapper注解
  • 编写sql映射文件并绑定mapper接口
  • 在application.yaml中指定Mapper配置文件的位置,以及指定全局配置文件的信息 (建议;配置在mybatis.configuration
    2.注解模式
    1. @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
    2. public class ResourceProperties {
    3.         private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
    4.                         "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
    5.         /**
    6.          * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
    7.          * /resources/, /static/, /public/].
    8.          */
    9.         private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
    复制代码
    3.混合模式
    1. @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
    2. public class ResourceProperties {
    3.         private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
    4.                         "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
    5.         /**
    6.          * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
    7.          * /resources/, /static/, /public/].
    8.          */
    9.         private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
    复制代码
    最佳实战:

    • 引入mybatis-starter
    • 配置application.yaml中,指定mapper-location位置即可
    • 编写Mapper接口并标注@Mapper注解
    • 简单方法直接注解方式
    • 复杂方法编写mapper.xml进行绑定映射
    • @MapperScan("com.atguigu.admin.mapper") 简化,其他的接口就可以不用标注@Mapper注解

4、整合 MyBatis-Plus 完成CRUD


  • 什么是MyBatis-Plus

    • MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
      mybatis plus 官网
      建议安装 MybatisX 插件

  • 整合MyBatis-Plus

      1.     @RequestMapping(value = "/user",method = RequestMethod.GET)
      2.     public String getUser(){
      3.         return "GET-张三";
      4.     }
      5.     @RequestMapping(value = "/user",method = RequestMethod.POST)
      6.     public String saveUser(){
      7.         return "POST-张三";
      8.     }
      9.     @RequestMapping(value = "/user",method = RequestMethod.PUT)
      10.     public String putUser(){
      11.         return "PUT-张三";
      12.     }
      13.     @RequestMapping(value = "/user",method = RequestMethod.DELETE)
      14.     public String deleteUser(){
      15.         return "DELETE-张三";
      16.     }
      17.         @Bean
      18.         @ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
      19.         @ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
      20.         public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
      21.                 return new OrderedHiddenHttpMethodFilter();
      22.         }
      23. //自定义filter
      24.     @Bean
      25.     public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
      26.         HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
      27.         methodFilter.setMethodParam("_m");
      28.         return methodFilter;
      29.     }
      复制代码
    • 自动配置

      • MybatisPlusAutoConfiguration 配置类,MybatisPlusProperties 配置项绑定。mybatis-plus:xxx 就是对****mybatis-plus的定制
      • SqlSessionFactory 自动配置好。底层是容器中默认的数据源
      • mapperLocations 自动配置好的。有默认值。***classpath*:/mapper/*/*.xml;任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。  建议以后sql映射文件,放在 mapper下
      • 容器中也自动配置好了 SqlSessionTemplate
      • @Mapper 标注的接口也会被自动扫描;建议直接 @MapperScan("com.atguigu.admin.mapper") 批量扫描就行

    • 优点:

      • 只需要我们的Mapper继承 BaseMapper 就可以拥有crud能力

    • CRUD功能

        1. spring:
        2.   mvc:
        3.     hiddenmethod:
        4.       filter:
        5.         enabled: true   #开启页面表单的Rest功能
        复制代码
        1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        2.                 HttpServletRequest processedRequest = request;
        3.                 HandlerExecutionChain mappedHandler = null;
        4.                 boolean multipartRequestParsed = false;
        5.                 WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
        6.                 try {
        7.                         ModelAndView mv = null;
        8.                         Exception dispatchException = null;
        9.                         try {
        10.                                 processedRequest = checkMultipart(request);
        11.                                 multipartRequestParsed = (processedRequest != request);
        12.                                 // 找到当前请求使用哪个Handler(Controller的方法)处理
        13.                                 mappedHandler = getHandler(processedRequest);
        14.                
        15.                 //HandlerMapping:处理器映射。/xxx->>xxxx
        复制代码


NoSQL

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings)散列(hashes)列表(lists)集合(sets)有序集合(sorted sets) 与范围查询, bitmapshyperloglogs地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication)LUA脚本(Lua scripting)LRU驱动事件(LRU eviction)事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
1、Redis自动配置
  1.         protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
  2.                 if (this.handlerMappings != null) {
  3.                         for (HandlerMapping mapping : this.handlerMappings) {
  4.                                 HandlerExecutionChain handler = mapping.getHandler(request);
  5.                                 if (handler != null) {
  6.                                         return handler;
  7.                                 }
  8.                         }
  9.                 }
  10.                 return null;
  11.         }
复制代码

自动配置:

  • RedisAutoConfiguration 自动配置类。RedisProperties 属性类 --> spring.redis.xxx是对redis的配置
  • 连接工厂是准备好的。LettuceConnectionConfiguration、JedisConnectionConfiguration
  • 自动注入了RedisTemplate : xxxTemplate;
  • 自动注入了StringRedisTemplate;k:v都是String
  • key:value
  • 底层只要我们使用 StringRedisTemplate、****RedisTemplate就可以操作redis
redis环境搭建
1、阿里云按量付费redis。经典网络
2、申请redis的公网连接地址
3、修改白名单  允许0.0.0.0/0 访问
2、RedisTemplate与Lettuce
  1. @Configuration                                                                                                                                                                                                                                                      
  2. public class SpringBootConfig implements WebMvcConfigurer {                                                                                                                                                                                                         
  3.    @Override                                                                                                                                                                                                                                                      
  4.    public void configurePathMatch(PathMatchConfigurer configurer) {                                                                                                                                                                                                
  5.       UrlPathHelper urlPathHelper = new UrlPathHelper();                                                                                                                                                                                                         
  6.       urlPathHelper.setRemoveSemicolonContent(false);                                                                                                                                                                                                            
  7.       configurer.setUrlPathHelper(urlPathHelper);                                                                                                                                                                                                                 
  8.    }                                                                                                                                                                                                                                                               
  9. }
复制代码
3、切换至jedis
  1.         protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
  2.                 if (this.handlerMappings != null) {
  3.                         for (HandlerMapping mapping : this.handlerMappings) {
  4.                                 HandlerExecutionChain handler = mapping.getHandler(request);
  5.                                 if (handler != null) {
  6.                                         return handler;
  7.                                 }
  8.                         }
  9.                 }
  10.                 return null;
  11.         }                    redis.clients            jedis        
复制代码
  1. @Override
  2.         public boolean supportsParameter(MethodParameter parameter) {
  3.                 Class<?> paramType = parameter.getParameterType();
  4.                 return (WebRequest.class.isAssignableFrom(paramType) ||
  5.                                 ServletRequest.class.isAssignableFrom(paramType) ||
  6.                                 MultipartRequest.class.isAssignableFrom(paramType) ||
  7.                                 HttpSession.class.isAssignableFrom(paramType) ||
  8.                                 (pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||
  9.                                 Principal.class.isAssignableFrom(paramType) ||
  10.                                 InputStream.class.isAssignableFrom(paramType) ||
  11.                                 Reader.class.isAssignableFrom(paramType) ||
  12.                                 HttpMethod.class == paramType ||
  13.                                 Locale.class == paramType ||
  14.                                 TimeZone.class == paramType ||
  15.                                 ZoneId.class == paramType);
  16.         }
复制代码
JUnit5单元测试

生产指标监控

SpringBoot核心原理解析

SpringBoot2场景整合

虚拟化技术

安全控制

缓存技术

消息中间件

分布式入门

SpringBoot2响应式编程


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表