SpringBoot从入门到入门学习笔记

1 篇文章 0 订阅
1 篇文章 0 订阅

目录

SpringBoot

一、环境

二、spring Boot和spring

2.1springBoot能做什么

2.2spring Boot的优点

三、微服务

3.1、基本概念

3.2分布式

3.3云原生

四、Spring Boot入门

4.1、官方文档的查看

4.2、Hello World

4.2.1设置maven

4.2.2创建hello world

4.3、Spring Boot的特点

4.3.1、依赖管理

4.3.2、自动装配

4.4、容器功能

4.4.1、组件添加

4.4.2、条件装配

4.4.3、原生配置文件引入

4.5、自动配置原理

4.5.1、@SpringBootApplication注解

4.5.3自动装配原理

4.6小结

五、开发小技巧

5.1、Lombok插件

5.2、dev-tools

5.3、Spring Initailizr自动创建spring Boot项目

六、Spring Boot核心功能

6.1、配置文件

1、文件类型

1.2.2、基本语法

1.2.3、数据类型

1.2.4、提示信息

1.2.5、读取配置内容

6.2、web开发

6.2.1、静态资源访问

6.2.2、欢迎页面

6.2.3、自定义 Favicon

6.2.4、静态资源配置原理

2.4.2、关于配置类

6.2.5、请求参数处理

6.3、数据访问

6.3.1、配置数据源

6.3.2、数据的自动配置类

6.3.3、Druid数据源

6.3.4、整合mybatis操作

6.4、单元测试

6.4.1、基本概念

6.4.2、常用注解

6.4.3、断言

6.4.4、嵌套测试

6.4.5、参数化测试

6.5、指标监控

6.6、高级特性

6.6.1、Profile功能

6.6.2、内部配置加载顺序

6.6.3、外部配置加载顺序

6.6.4、自定义stater

七、结束


SpringBoot

一、环境

  • spring Boot2要求Java要在1.8之上,maven要在3.3之上

二、spring Boot和spring

2.1springBoot能做什么

  • spring的生态覆盖了:web开发(Spring Framework),数据访问(SpringData),安全控制(SpringSecurity),分布式(SpringCloud),消息服务(AMQP)、移动开发(SpringMobile)、批处理(Batch).......

  • spring Boot可以快速创建出生产级别的spring应用,是一个高层框架,底层是spring,它可以帮助我们整合spring的整个生态圈,让我们开始编程

  • 由于spring5进行了重大升级,所以有了响应式编程,老版本使用的是servlet那一套,而boot2使用了响应式的编程

2.2spring Boot的优点

  1. 创建一个独立的spring的应用

  2. 内嵌了web服务器,不再需要将代码打成war包放入tomcat服务器

  3. 使用stater依赖,简化构建配置,避免jar包冲突

  4. 自动配置spring以继第三方应用

  5. 提供生产级别的监控,外部配置

  6. 无代码产生,无需编写xml

三、微服务

3.1、基本概念

  • 微服务是一种架构风格

  • 一个应用拆分为一组小型服务

  • 每个服务运行在自己的进程内,可以独立部署和升级

  • 服务之间需要通信使用轻量级的HTTP

  • 服务围绕着业务功能拆分

  • 可以由全自动部署机制独立部署

  • 去中心化,服务自治,服务可以使用不同语言,不同存储技术

3.2分布式

  • 由于微服务的出现,自然也就出现了分布式;而分布式的出现也引出了分布式的困难

    • 远程调用问题(a服务放在了3台机器,b服务放在了2台机器,c服务放在4台机器;abc呼啸调用就出现了远程调用问题。一般使用HTTP来解决远程调用的通信问题)

    • 服务发现(由于每一个服务都放在了多台机器,哪么那一台才是好的那一台是宕机的于是出现了服务发现问题)

    • 负载均衡(当服务全部是正常时,到底访问哪一个机器就需要负载均衡来解决了)

    • 服务容错(由于每个服务都是多台机器,若正在调用的机器发生了异常,或者网络出现了异常应该做什么反应)

    • 配置管理(因为一个服务放在了多台机器,修改配置时只改配置中心的配置即可,不需要将每一台机器都修改一次)

    • 服务监控(多台机器的运行状况)

    • 链路追踪(abc多个服务之间的调用情况)

    • 日志管理(多台机器的多个日志收集问题)

    • 任务调度(定时任务应该在哪一台机器运行)

    • ......

  • 解决大方案:SpringBoot+SpringCloud

3.3云原生

  • 服务自愈(若生产某一台机器宕机,如何重新拉起一台)

  • 弹性伸缩(流量高峰增加机器,流量低峰减少机器)

  • 服务隔离(一台机器的多个服务互不影响)

  • 自动化部署(由于机器和服务模块众多,可以自动化)

  • 灰度发布(发布时,先发布一台机器,再逐个替换)

  • 流量治理(治理低性能机器少连接,高性能的机器多连接)

  • ......


四、Spring Boot入门

4.1、官方文档的查看

  • 官方参考文档从入门到精通,其实学习springBoot的时候我们都是学过spring以及mvc的老手了,更多的是学会查看boot的官方文档

Spring Boot Reference Documentation

4.2、Hello World

4.2.1设置maven

maven要在3.5之上,其次使用阿里云镜像会快一点,使用1.8编译

<mirrors>
      <mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>central</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
      </mirror>
  </mirrors>
 
  <profiles>
         <profile>
              <id>jdk-1.8</id>
              <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>1.8</jdk>
              </activation>
              <properties>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
                <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
              </properties>
         </profile>
  </profiles>

4.2.2创建hello world

  1. 在idea中创建一个maven项目,不需要选择模板

  2. 在pom文件中加入如下代码

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
    </parent>
​
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

3.创建main方法,告诉springBoot这是一个spring Boot项目

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

4.业务逻辑

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello(){
        return "hello boot";
    }
}

5.可以创建一个application.properties修改配置

server.port=8888

6.简化部署,可以打成一个jar包直接java -jar xxx.jar来运行

 <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 要取消掉cmd中的快速编辑模式,要不然会卡住不动

  • 为什么spring Boot的jar包可以直接运行

4.3、Spring Boot的特点

4.3.1、依赖管理

  • 父项目做的依赖

<!--每一个boot项目都会依赖这个parent,而这个parent又依赖于dependencies,
在dependencies中定义了常用的依赖的版本号,也就是版本仲裁机制--> 
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
    </parent>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.5.3</version>
  </parent>
  • 自动仲裁:无需关注版本号,引入默认依赖时不需要写版本号,当然也可以修改默认的版本号,例如想要更改mysql的驱动,在pom文件中加入一个properties修改为想要的mysql版本号Maven会就近配置

<properties>
      <mysql.version>5.1.43</mysql.version>
</properties>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.version}</version>
</dependency>
  • 导入各类starter场景启动器

1.官方给我出的各类场景驱动器都是 spring-boor-starter-*的格式   *就是各类场景
2.只要引入starter,这个场景所需要的常规依赖都会自动导入
3.spring Boot几乎涵盖了所有的场景
https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
4.除了官方给出的starter还会有一些第三方给出的starter,包括我们也可以自定义starter格式一般都是:*-spring-boot-starter
5.所有的场景启动器都是依赖于
 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.5.3</version>
      <scope>compile</scope>
 </dependency>

4.3.2、自动装配

  • 先有个概念和体验,后面具体来说;参照这一片详细内容http://t.csdn.cn/AQPdy

  • 例如我们引入web-starter后自动配置了tomcat以及springMVC等

  • 以mvc为例

    • 在我们引入web-starter的时候引入了mvc的全套组件

      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>5.3.9</version>
          <scope>compile</scope>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.3.9</version>
          <scope>compile</scope>
        </dependency>

    而且帮我们配好了mvc常见的组件例如:字符集编码,文件上传等

    • 默认的包结构(自动扫包机制)

      • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来

      • 无需以前的包扫描配置

      • 想要改变扫描路径,@SpringBootApplication(scanBasePackages="com.yang")

        • 或者@ComponentScan 指定扫描路径

  • 各种配置拥有默认值

    • 默认配置最终都是映射到某个类上,如:MultipartProperties

    • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象

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

    • 引入了哪些场景这个场景的自动配置才会开启

    • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

4.4、容器功能

4.4.1、组件添加

  • @Configuration注解

    • 该注解告诉spring Boot该类为一个配置类,在类中使用@Bean来添加组件

    • Full模式

      • 默认情况是full模式,spring Boot会每次检查容器中的组件,若已经有,会使用已有的组件,若没有会进行注册

      • 若有组件依赖时,会使用full模式,其他使用lite模式

    • Lite模式

      • 运行时不用生成CGLIB子类,提高运行性能,降低启动时间,可以作为普通类使用。但是不能声明@Bean之间的依赖

      • 也就是将proxyBeanMethods设置为FALSE,每次调用@Bean就都是单独的一个对象,而不是从容器中取了

  • 之前的@Component、@Controller、@Service、@Repository也可以进行组件添加

  • @Import:可以导入多个类,底层是一个数组;给容器中自动创建出该类的组件,默认组件名字及时全类名

4.4.2、条件装配

  • @Conditional注解:满足某个条件才进行组件的注入

  • 可以加在方法也可以直接加在类上面

 @Bean
    @ConditionalOnBean(Pet.class)
    public User user01(){
        User user = new User("张三", 18);
        user.setPet(pet01());
        return user;
    }
//以该注解为例,当容器中有Pet类型的bean时才对user进行注入

4.4.3、原生配置文件引入

  • @ConfigurationProperties(prefix = "mycar")注解加在bean上面,将properties内容绑定到bean上面

  • 因为只有在容器的组件才能使用spring Boot的强大功能,所以要在bean上面添加@Component注解才能将其放入容器中,也就是让@ConfigurationProperties注解生效

  • 当然有时候我们需要用的是第三方的bean,没法用@Component注解,我们可以在我们的配置类上面添加@EnableConfigurationProperties(bean.class)代表开启配置绑定功能,会把这个bean自动注册到容器中

4.5、自动配置原理

4.5.1、@SpringBootApplication注解

  • 该注解是一个复合注解由 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan这三个注解构成

  • 其中@SpringBootConfiguration注解代表当前类是一个配置类,是spring Boot的核心配置类

  • @ComponentScan注解可以指定扫描包

  • @EnableAutoConfiguration该注解是spring Boot自动装配的核心注解

4.5.2、@EnableAutoConfiguration注解

  • 该注解也是合成注解由@AutoConfigurationPackage、@Import这两个注解构成

  • 其中@AutoConfigurationPackage注解是自动配置包的意思,主要是指定了包默认规则

    @Import({Registrar.class})
    public @interface AutoConfigurationPackage {
    //Import注解为spring Boot注册一系列的组件
    //利用Registrar方法将指定包下的所有组件都注入;也就是主应用程序所在的包,所以这就是为什么默认包路径是和主应用程序的路劲是一致的
    //获取包路径
    //  (new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames()
  • @Import({AutoConfigurationImportSelector.class})注解批量导入组件

    • AutoConfigurationImportSelector是关键类,而这个类中的 getAutoConfigurationEntry方法中的getCandidateConfigurations(annotationMetadata, attributes)---->loadFactoryNames--->loadSpringFactories获取到所有需要导入到容器中的配置类

    • 利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件

    • META-INF/spring.factories位置来加载一个文件。默认扫描当前系统里面所有META-INF/spring.factories位置的文件 spring-boot-autoconfigure-2.5.3.RELEASE.jar包里面也有META-INF/spring.factories

    • spring.factories 文件里面写死了spring-boot一启动就要给容器中加载的所有配置类,一共127个xxxAutoConfiguration;然后spring Boot会根据按条件加载的规则(@Conditional),加载需要的组件

4.5.3自动装配原理

  1. spring Boot中最重要的注解就是@SpringBootApplication,而这个注解时一个复合注解,由三个注解合成,其中实现自动装配的核心注解是@EnableAutoConfiguration,其中@Import({AutoConfigurationImportSelector.class})注解是重点

  2. 利用AutoConfigurationImportSelector类跳转到SpringFactoriesLoaderloader类中的loderSpringFactories方法将SpringBoot中的META-INF/spring.factories加载进来

  3. 工厂里面定义了许多的xxxAutoConfiguration,这些xxxAutoConfiguration按照条件生效,之后从xxxproperties中取值(EnableConfigurationProperties绑定了需要使用的properties,这个注解会将xxxproperties注册到我们的容器中),而如果我们对属性进行了修改@ConditionalOnProperty(按条件生效)这个注解就会发挥作用,从application.properties中拿值

4.6小结

  1. 引入场景依赖https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter

  2. 查看自动配置了哪些(选做)

  • 自己分析,引入场景对应的自动配置一般都生效了
  • 配置文件中debug=true开启自动配置报告。Negative(不生效)\Positive(生效)

     3. 是否需要修改

  • 参照文档修改配置项
  • Common Application Properties
  • 自己分析。xxxxProperties绑定了配置文件的哪些。
  • 自定义加入或者替换组件
  • @Bean、@Component。。。
  • 自定义器 XXXXXCustomizer,就是我们可以使用@Bean注入一个我们自定义的类,不使用默认配置的类
  • ......

五、开发小技巧

5.1、Lombok插件

  • 简化JavaBenan的开发,打开settings,在plugins里面搜索lombok,安装。

<!--1.pom文件引入lombok依赖-->
<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
 </dependency>
<!--2.在bean上添加想要的注解,例如get/set方法可以使用@Data注解,以及@ToString等注解;也可以使用@Slf4j添加日志-->

5.2、dev-tools

  • 不要钱的热部署,其实就是自动重启

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
<!--修改代码后直接CTRL+F9就可以了-->

5.3、Spring Initailizr自动创建spring Boot项目

  • 在创建model时使用Spring Initailizr可以自动添加我们想要的场景,会自动搭建好主体架构,配置类,依赖

  • 勾选需要使用的场景和工具类


六、Spring Boot核心功能

6.1、配置文件

1、文件类型

1.1、properties文件;和之前spring中的properties文件使用一致

1.2、yaml文件

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

  • 非常适合用来做以数据为中心的配置文件

1.2.2、基本语法

  • key: value;kv之间有空格

  • 大小写敏感

  • 使用缩进表示层级关系

  • 缩进不允许使用tab,只允许空格

  • 缩进的空格数不重要,只要相同层级的元素左对齐即可

  • '#'表示注释

  • 字符串无需加引号,如果要加,单引号与双引号,对字符串内容含义不同

    • 例如\n单引号不会换行,双引号会换行

1.2.3、数据类型

  • 字面量:基本数据类型

    • k: v

    • date类型时需要添加时区

  • 对象,map,list,object

    行内写法:  k: {k1:v1,k2:v2,k3:v3}
    #或
    k: 
    	k1: v1
      k2: v2
      k3: v3
  • 数组和set

行内写法:  k: [v1,v2,v3]
#或者
k:
 - v1
 - v2
 - v3

1.2.4、提示信息

  • 我们自定义得bean没有提示需要在pom文件中添加spring-boot-configuration-processor

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

 <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--打包时不对其进行打包,因为没必要-->
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-configuration-processor</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

1.2.5、读取配置内容

  1. @Value:直接在属性上使用注解使用"${配置文件中的内容}"

  2. Environment:需要注入这个对象,使用这个对象的getProperty("配置文件属性名称")

  3. @ConfigurationProperties:在实体类上标注该注解,prefix = "person",指定配置文件的属性名称,实体类的属性就会和配置文件属性对应;要在实体类上添加@Component注解配合使用,或者在配置类使用EnableConfigurationProperties注解将bean注入容器

6.2、web开发

6.2.1、静态资源访问

  • 关于是springBoot中web的官方文档Web

  • 默认情况下,Spring Boot 从类路径中名为/static(或/public/resources/META-INF/resources)的目录获取静态资源

6.2.2、欢迎页面

  • 静态资源路径下 index.html

  • 可以配置静态资源路径
  • 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
<!--yaml配置-->
spring:
#  mvc:
#    static-path-pattern: /res/**   这个会导致welcome page功能失效

  resources:
    static-locations: [classpath:/haha/]
  • controller能处理/index

6.2.3、自定义 Favicon

favicon.ico 放在静态资源目录下即可。

spring:
#  mvc:
#    static-path-pattern: /res/**   这个会导致 Favicon 功能失效

6.2.4、静态资源配置原理

  • SpringBoot启动默认加载 xxxAutoConfiguration 类(自动配置类)

  • SpringMVC功能的自动配置类 WebMvcAutoConfiguration,生效

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {}
  • 给容器中配了什么

@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
	@Order(0)
	public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
  • 配置文件的相关属性和xxx进行了绑定。WebMvcProperties:spring.mvc; ResourceProperties:spring.resources

2.4.2、关于配置类

  • 配置类只有一个有参构造器

	//有参构造器所有参数的值都会从容器中确定
//WebProperties webProperties;获取和spring.web绑定的所有的值的对象
//WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
//ListableBeanFactory beanFactory Spring的beanFactory
//HttpMessageConverters 找到所有的HttpMessageConverters
//ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。=========
//DispatcherServletPath  
//ServletRegistrationBean   给应用注册Servlet、Filter....

  public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
           。。。
        }
  • 资源的默认处理方式

public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
                this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                    registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                    if (this.servletContext != null) {
                        ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                        registration.addResourceLocations(new Resource[]{resource});
                    }

                });
            }}
//this.resourceProperties.getStaticLocations()获取路径; this.mvcProperties.getStaticPathPattern()获取前缀(/**)
  • 欢迎页的配置

@Bean
        public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
            WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
            。。。
            return welcomePageHandlerMapping;
        }
其中 new WelcomePageHandlerMapping 决定了只能在/下面才能使用;favicon.ico同理

    WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
        //要用欢迎页功能,必须是/**
        if (welcomePage != null && "/**".equals(staticPathPattern)) {
            logger.info("Adding welcome page: " + welcomePage);
            this.setRootViewName("forward:index.html");
        } else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
              // 调用Controller  /index
            logger.info("Adding welcome page template: index");
            this.setRootViewName("index");
        }}

6.2.5、请求参数处理

2.5.1关于rest风格

  • Rest风格支持(使用HTTP请求方式动词来表示对资源的操作

  • 核心在于filter即HiddenHttpMethodFilter(它会将除了get和post支持的方法之外 的方法进行转换)

    • 在springBoot中我们对mvc进行了自动配置,所以在使用时我们需要在yaml中手动打开(因为使用postman等工具不需要转换,可以直接访问)

    • @Bean
      	@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
      	@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
      	public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
      		return new OrderedHiddenHttpMethodFilter();
      	}
  • 有上↗可知,我们在容器中没有HiddenHttpMethodFilter类时才会开启该配置,所以我们也可以自定义一个HiddenHttpMethodFilter,这样可以将“_methord”自定义为自己喜欢的名字

  • rest实现原理

    1. 在表单提交的时候会有一个参数"_methord"

    2. 请求到达后会被拦截器拦截,将其"_methord"带的值获取,并判断该表单提交方式是否为post

    3. 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值即(PUT,DELETE,PATCH)

    4. 过滤器在放行时使用的wrapper,之后调用时方法就变成了原有的"_methord"(PUT,DELETE,PATCH)中的值

2.5.2、请求映射原理

  • springMvc的分析都是从DispatcherServletAutoConfiguration中引用的DispatcherServlet类的doDispatch()方法开始

  • 	// 找到当前请求使用哪个Handler(Controller的方法)处理
       				mappedHandler = getHandler(processedRequest);
  • 其中RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。

  • SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;

  • SpringBoot自动配置了默认 的 RequestMappingHandlerMapping

  • 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。

    • 如果有就找到这个请求对应的handler

    • 如果没有就是下一个 HandlerMapping

  • 我们需要一些自定义的映射处理,我们也可以自己给容器中放HandlerMapping

2.5.3、普通参数与注解

  • @PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、@CookieValue、@RequestBody

    • 第一个是rest风格中获取参数使用的注解

    • 第二个是获取请求头参数

    • 第三个是model

    • 第四个获取请求路径中的参数

    • 矩阵变量,默认是禁用的,需要手动开启

    • 获取cookie值,获取整个请求体

2.5.4、Servlet API

  • 我们可以传入一些原生的servlet来进行操作,例如WebRequest、ServletRequest、MultipartRequest、 HttpSession、等等

  • 其中 ServletRequestMethodArgumentResolver 可以解析以上的部分参数

2.5.5、复杂参数

  • MapModel(map、model里面的数据会被放在request的请求域 request.setAttribute)edirectAttributes( 重定向携带数据)ServletResponse(response)

  • Map、Model类型的参数,会返回 mavContainer.getModel();---> BindingAwareModelMap 是Model 也是Map

6.3、数据访问

6.3.1、配置数据源

  • 引入jdbc相关starter,jdbc-starter引入了数据源(HikariDataSource),jdbc,事务(spring-tx);没有导入数据库驱动,因为spring-boot并不知道你需要使用什么数据库

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
  • 导入数据库驱动,数据库的驱动要和数据库的版本对应,由于boot对版本进行了仲裁,所以当需要修改版本时,可以显示的写在version标签中,也可以在properties标签中修改<mysql.version>8.0.22</mysql.version>

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

6.3.2、数据的自动配置类

  • DataSourceAutoConfiguration该类是数据源的配置类,修改相关配置时使用spring.datasource,其中底层默认的数据库连接池是我们没有自定义才会自动配置

  • DataSourceTransactionManagerAutoConfiguration: 事务管理器的自动配置

  • JdbcTemplateAutoConfiguration: JdbcTemplate的自动配置,可以来对数据库进行crud

    • 可以修改这个配置项@ConfigurationProperties(prefix = "spring.jdbc") 来修改JdbcTemplate

    • @Bean@Primary JdbcTemplate;容器中有这个组件

  • JndiDataSourceAutoConfiguration: jndi的自动配置

  • XADataSourceAutoConfiguration: 分布式事务相关的

6.3.3、Druid数据源

  • 引入starter

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>
  • 扩展配置项 spring.datasource.druid

  • DruidSpringAopConfiguration.class, 监控SpringBean的;配置项:spring.datasource.druid.aop-patterns

  • DruidStatViewServletConfiguration.class, 监控页的配置:spring.datasource.druid.stat-view-servlet;默认开启

  • DruidWebStatFilterConfiguration.class, web监控配置;spring.datasource.druid.web-stat-filter;默认开启

  • DruidFilterConfiguration.class}) 所有Druid自己filter的配置

6.3.4、整合mybatis操作

  • 引入stater

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
  • 自动装配的东西

    • SqlSessionFactory: 自动配置好了

    • SqlSession:自动配置了 SqlSessionTemplate 组合了SqlSession

    • @Import(AutoConfiguredMapperScannerRegistrar.class);

    • Mapper: 只要我们写的操作MyBatis的接口标准了 @Mapper 就会被自动扫描进来

  • 基于配置方式的整合

    1. 再resource目录下需要一个mybatis的全局变量文件,和一个存放mapper.xml的文件夹;

    2. 在mapper接口上标注@Mapper注解,mapper接口和mapper.xml绑定好

    3. 在application.yaml中指定mapper.xml的位置,以及配置文件的位置或者配置configuration属性

    4. 如果数据库表中字段是带_的需要开启mybatis的驼峰命名规则,可以在全局变量文件中的<setting>标签的mapUnderscoreToCamelCase属性设置为true

    5. 也可以不写全局变量的配置文件直接在yaml中configuration下面设置即可(推荐)

  • 基于注解模式

    • 可以在mapper接口的方法上面写注解例如@Select,@Update,@Delete等

    • 简单的sql可以使用注解模式,不编写mapper.xml

  • 总结

    • 引入mybatis-starter

    • 配置application.yaml中,指定mapper-location位置即可

    • 编写Mapper接口并标注@Mapper注解

    • 简单方法直接注解方式,复杂方法编写mapper.xml进行绑定映射

  • @MapperScan("com.atguigu.admin.mapper") 简化,其他的接口就可以不用标注@Mapper注解(不推荐)

6.4、单元测试

6.4.1、基本概念

  • springBoot2引入了Junit5作为单元测试的默认库

  • 在创建项目时回默认加入,也可以自个儿加入Junit5的stater进行使用

  • 若要使用spring中的东西,例如 @Transactional(当有dml语句时,操作完成后,回自动回滚数据库的数据)要在类上添加@SpringBootTest注解,以加载spring中的东西

6.4.2、常用注解

  • JUnit 5 User Guide 官网地址

  • @Test :表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试

  • @DisplayName :为测试类或者测试方法设置展示名称

  • @BeforeEach :表示在每个单元测试之前执行

  • @AfterEach :表示在每个单元测试之后执行

  • @BeforeAll :表示在所有单元测试之前执行

  • @AfterAll :表示在所有单元测试之后执行

  • @Tag :表示单元测试类别,类似于JUnit4中的@Categories

  • @Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore

  • @Timeout :表示测试方法运行如果超过了指定时间将会返回错误

6.4.3、断言

  • 断言(assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证。这些断言方法都是 org.junit.jupiter.api.Assertions 的静态方法

方法说明
assertEquals判断两个对象或两个原始类型是否相等
assertNotEquals判断两个对象或两个原始类型是否不相等
assertSame判断两个对象引用是否指向同一个对象
assertNotSame判断两个对象引用是否指向不同的对象
assertTrue判断给定的布尔值是否为 true
assertFalse判断给定的布尔值是否为 false
assertNull判断给定的对象引用是否为 null
assertNotNull判断给定的对象引用是否不为 null
assertArrayEquals判断传入的两个数组是否相同
assertAll组合断言,只有组合中两个断言全部成功才算成功
fail快速失败,使用该方法,直接失败
  • JUnit 5 中的前置条件(assumptions【假设】)类似于断言,不同之处在于不满足的断言会使得测试方法失败,而不满足的前置条件只会使得测试方法的执行中止,测试结果为跳过而不是错误;两者都不会执行之后的代码。前置条件可以看成是测试方法执行的前提,当该前提不满足时,就没有继续执行的必要。

6.4.4、嵌套测试

  • JUnit 5 可以通过 Java 中的内部类和@Nested 注解实现嵌套测试,从而可以更好的把相关的测试方法组织在一起。在内部类中可以使用@BeforeEach 和@AfterEach 注解,而且嵌套的层次没有限制。(了解)

6.4.5、参数化测试

  • 要使用参数话测试就不能使用@Test注解 了,而应该使用@ParameterizedTest注解,来告诉Junit这是一个参数化测试方法

  • @ValueSource: 为参数化测试指定入参来源,支持八大基础类以及String类型,Class类型

    @NullSource: 表示为参数化测试提供一个null的入参

    @EnumSource: 表示为参数化测试提供一个枚举入参

    @CsvFileSource:表示读取指定CSV文件内容作为参数化测试入参

    @MethodSource:表示读取指定方法的返回值作为参数化测试入参(注意方法返回需要是一个流)

6.5、指标监控

  • 引入actuator的stater

  • 配置文件中打开监控

management:
  endpoints:
    enabled-by-default: true #暴露所有端点信息
    web:
      exposure:
        include: '*'  #以web方式暴露

6.6、高级特性

6.6.1、Profile功能

  • application.properties的配置优先于application.yaml

  • 为了便于环境切换,我们会使用profile功能进行环境的切换激活

配置方式

  • 多profile文件方式 和 yaml文档方式

    • 可以在resource目录下创建多个application-xx.properties文件;在application.properties中使用spring.profiles.active=dev来激活某一个properties

    • 在application.yaml文件中使用---来区分文件,使用on-profile来命名每一个文件;同样使用spring.profiles.active=dev来激活某一个文件;注意使用yaml就把properties给关掉,否则回去找properties中的配置

    • 不管是properties还是yaml不指定文件的情况下就都是原有的默认配置

激活方式

  • 配置文件 虚拟机参数 命令行参数

  • 也可以在虚拟机参数里面填写 -Dspring.profiles.active=dev 来指定启动文件的配置

  • 可以将我们的项目打成一个jar包,在jar包所在的目录直接使用Java -jar来运行jar并且在后面添加--spring.profiles.active=dev来指定激活哪个配置

6.6.2、内部配置加载顺序

  1. classpath 根路径

  2. classpath 根路径下config目录

  3. jar包当前目录

  4. jar包当前目录的config目录

  5. /config子目录的直接子目录

  • 以上顺序越往下优先级越高,即如果1-5中有同一配置,那么5中的会生效,其他均不生效;若有不同的配置,则会生效

6.6.3、外部配置加载顺序

  • Core Features

  • 指定环境优先,外部优先,后面的可以覆盖前面的同名配置项

6.6.4、自定义stater

  • stater主要有两部分组成,一部分是启动器,也就是pom文件中的xxx-stater;还有一部分就是自动配置的包,即具体的代码

    • 场景启动器一般是没有任何源码,只是声明了我们需要哪些依赖

    • 自动配置包,这个包中是我们的具体实现代码

      • 首先我们准备一个bean也就是xxxProperties,将该类使用@ConfigurationProperties注解与配置类绑定

      • 其次我们需要一个具体的实现方法,例如xxxService,在该类中有我们具体的业务逻辑代码,并将我们需要使用的properties文件使用Autowrite注入

      • 之后还要准备一个配置类,将service注入容器中(因为在第一步的service中我们不会将其注入容器);并且使用EnableConfigurationProperties注解,将实体类和配置文件的关联打开以及注入容器;还可以使用ConditionOnMissingBean等注解,按照具体情况进行条件判断

      • 最后需要在resource目录下建立一个META-INF目录,创建spring.faction文件,将我们的配置类XXXAutoConfiguration类的类路径放入其中,这样在springBoot在启动时就可以加载到我们自定义的配置类了

    • 在创建自定义stater的时候,我们需要两个工程,第一个就是场景启动器,也就是xxx-stater;建个普通maven工程就可以了;在该项目中的pom文件中将自动配置包引入

    • 最后使用maven直接install打包既可,在其他项目使用时,直接引入场景启动器即可,即一开始建的xxx-spring-boot-stater

  • 详细过程http://t.csdn.cn/aAe2W

七、结束

  • 入门就先入到这,springboot我们已经掌握了基本使用;基本原理也有了了解,到后期我们还会深入学习web场景下的具体原理,以及整合mybatis-plus,redis等场景
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值