Springboot

SpringBoot快速入门

  • Spring cloud:分布式应用
  • Spring Security:web安全

0.知识回顾

  • javaSE:主要学习OOP的思想
  • MySql:持久化
  • html+css+js+jquery+框架:视图层
  • ssm:框架,简化了开发,配置较为复杂

war:在tomact中运行

  • Spring再简化:SpringBoot-jar,内嵌tomcat,微服务架构
  • 服务越来越多:Springcloud

1.简介

1.1学习总结

Springboot学习路线

  • 是什么
  • 配置如何编写yaml
  • 自动装配原理
  • 集成web开发:业务核心
  • 集成数据库Druid:分布式数据分析平台
  • 分布式开发:Dubbo+zookeeper
  • swagger:接口文档
  • 任务调度
  • SpringSecurity:Shiro

SpringClud

  • 微服务
  • 快速入门
  • Restful
  • Eureka
  • Ribbon
  • Feign
  • Hystrix
  • Zuul路由网关
  • SpringCloud Config

1.2环境要求

  • jdk:1.8
  • Spring Boot2.xx
  • Maven
  • IDEA

1.3Spring boot

  • Spring:一个轻量级开发框架,为了解决企业级应用开发的复杂性而创建的,简化开发

如何简化开发

  • 基于Pojo轻量级和最小侵入性编程
  • 通过IOC,依赖注入和面向接口实习那松耦合
  • 基于切面(AOP)和惯例式声明编程
  • 通过切面和模板减少样式代码

SpringBoot

java web开发框架,Spring boot 帮我们简单,快速的创建一个独立的,生产级别的Spring应用,大多数SpringBoot 应用只需要少量配置即可快速整合Spring平台和第三方技术

特性

  • 快速创建 独立SpringYingyong
  • 直接嵌入 Tomact,Jetty
  • 提供可选的starter,简化应用整合
    • 为每个场景准备了一个依赖
  • 没有冗余代码和XML配置要求

1.4什么是微服务

  • 微服务是一种架构模式,提倡单一应用程序划分一组小服务,每个服务运行在自己独立的进程内,服务之间,互相协调,互相配置,为用户提倡最终的价值;
  • 服务之间采用轻量级的通信机制互相沟通,每个服务围绕具体的业务构建,并且能够被独立的部署在生产环境中,
  • 尽量避免统一的,集中式管理的服务管理机制,对具体的一个服务而言,根据上下文,选择合适的语言,工具,对齐构建,可以有一个非常轻量的集中式管理来协调业务,可以使用不同的语言编写,也可以用不同的数据储存

1.5创建一个Springboot项目

  • 在springboot网站创建后下载(不推荐,IDEA已经集成Springboot开发环境)
  • 直接使用IDEA创建

Springboot_第1张图片

项目结构见上图

2.原理初探

2.1pom.xml

  • 父依赖

    <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.7.14version>
            <relativePath/> 
        parent>
    

    这里导入了一个父项目,用来管理项目的资源过滤和插件

  • 我们查看其文件

     <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-dependenciesartifactId>
        <version>2.7.14version>
      parent>
    

    这是真正管理所有依赖版本的地方,SpringBoot的版本控制中心

所以我们导入大部分依赖,可以不写版本

web启动器

<dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
  • 导入这个依赖会,会自动导入web环境的所有依赖

  • 所以我们使用什么功能,只需要找到对应的启动器即可

2.2主启动类

@SpringBootApplication//标注这是一个springboot应用
public class SpringStudyApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringStudyApplication.class, args);//通过反射将对象启动
    }

}

注解

@SpringBootApplication注解下

  • @SpringBootConfiguration:Springboot配置类

    • @Configuration:spring配置类,对应spring的xml文件,相当于原来向bean注入的bean.xml文件

    • @Component:spring组件负责启动应用

  • @EnableAutoConfiguration:开启自动配置功能

    • @AutoConfigurationPackage:自动配置包

      @Import({Registrar.class})
      public @interface AutoConfigurationPackage {
      }
      
      • imort:Spring底层注解,给容器导入一个组件

      • @Import(AutoConfigurationPackages.Registrar.class):自动配置包注册

        // 获得候选的配置
        protected List getCandidateConfigurations(AnnotationMetadata
        metadata, AnnotationAttributes attributes) {
          //这里的getSpringFactoriesLoaderFactoryClass()方法
          //返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration
          List configurations =
        SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryCl
        ass(), 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;
        }
        

        继续向下查看你,该方法调用了 SpringFactoriesLoader的静态方法,我们查看该方法

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

        继续点击

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

        多次出现一个文件spring.factories,我们搜索打开

        会发现很多自动配置的文件,这就是自动配置的根源所在

结论

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

方法

分析方法主要分两部分呢,一部分是实例化,一部分是方法的执行

  • SpringBootApplication实例化

    • 判断应用是普通项目还是web项目
    • 查找加载所有可用初始化器,设置到initalizers属性中
    • 找出所有应用程序监听器,设置到listeners属性中
    • 推断并设置main方法的定义类,找到运行的主类
  • run()方法

    Springboot_第2张图片

3.配置文件

3.1yaml语法

可以有两种配置文件,名称是固定的

  • application.properties:key=value

  • application.yml: key: 空格 value;强大之处在于可以给实体类赋值

  • 标记语言:以前的配置文件,大多数使用xml配置,

    xml配置

    <server>
      <port>8081<port>
    server>
    

    yaml配置

    server:
    prot: 8080
    
    • 空格不能省略
    • 缩进控制层级关系
    • 大小写十分敏感

3.2yaml注入配置文件

yaml更加强大的地方在于他可以直接给实体类进行赋值

3.2.1原始赋值方法

  1. 编写实体类

    @Component  //注册bean到容器中,使得这个类可以被扫描到
    public class User {
        private String name;
        private Integer age;
        //有参无参构造、get、set方法、toString()方法  
    }
    
  2. 原来是如何给bean注入属性值的?? @Value,我们可以测试一下

    @Component //注册bean
    public class User {
        @Value("张飞")
        private String name;
        @Value("18")
        private Integer age;
    }
    
  3. 进行测试

    @SpringBootTest
    class SpringStudyApplicationTests {
        @Autowired//讲User注入进来
        User user;
        @Test
        void contextLoads() {
            System.out.println(user);
        }
    
    }
    
    

3.2.2通过yaml文件赋值

  1. 编写User类
/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
名字必须一样
*/
@Component
@ConfigurationProperties(prefix = "user")//指向对应的yaml文件中的对应配置
public class User {

    private String username;

    private Integer age;
}
  1. 配置文件

    #给user属性进行值的注入
    user:#与prefix相对应
      username: kobe
      age: 25
    
    
  2. 测试

    同上

3.2.3 指定配置文件加载

@PorpertySource:加载指定配置文件

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

  1. 在setting中将字符集设置为UTF-8

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gLYLVIVQ-1692879253166)(C:\Users\LuckyRui\AppData\Roaming\Typora\typora-user-images\image-20230824112930486.png)]

  2. 在代码中指定加载user.properties文件

    @Component
    @ConfigurationProperties(prefix = "user")
    @PropertySource("classpath:user.properties")//指定加载文件
    public class User {
    
        private String username;
    
        private Integer age;
    }
    
  3. 测试

占位符

  • 配置文件中还可使用占位符

    user:
         name: qinjiang${random.uuid} # 随机uuid
         age: ${random.int}  # 随机int
    

总结对比

1、@ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加
2、松散绑定:这个什么意思呢? 比如我的yaml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
3、JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性
4、复杂类型封装,yaml中可以封装对象 , 使用value就不支持。
使用场景

  • 配置yaml和配置properties都可以获取到值 , 但是强烈推荐 yaml;
  • 如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;
  • 如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!

4.JSR303数据检验和多环境切换

4.1JSR3.3

  • 作用:用来检验输入内容的(前端同样可以实现)
  • SpringBoot中使用@validated来检验数据,如果数据异常则会抛出异常,方便统一处理
  1. 导入对应的依赖

    <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starter-validationartifactId>
    dependency>
    
  2. 修改对应的实体类

    @Component
    @ConfigurationProperties(prefix = "user")
    @Validated//数据校验
    public class User {
        private String username;
        private Integer age;
         @Email(message = "邮箱格式错误")//必须是邮箱格式,否则发送邮箱格式错误
        private String email;
    }
    
    
  3. 测试同上

其他规则

@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;

空检查
@Null       验证对象是否为null
@NotNull    验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty   检查约束元素是否为NULL或者是EMPTY.

Booelan检查
@AssertTrue     验证 Boolean 对象是否为 true  
@AssertFalse    验证 Boolean 对象是否为 false  

长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  
@Length(min=, max=) string is between min and max included.

日期检查
@Past       验证 DateCalendar 对象是否在当前时间之前  
@Future     验证 DateCalendar 对象是否在当前时间之后  
@Pattern    验证 String 对象是否符合正则表达式的规则

.......等等
除此以外,我们还可以自定义一些数据校验规则

4.2 多环境切换

配置文件优先级

优先级1:项目路径下的config文件夹配置文件
优先级2:项目路径下配置文件
优先级3:资源路径下的config文件夹配置文件
优先级4:资源路径下配置文件
  • 配置名称application-{profile}.properties/yml

    • application-test.properties:测试环境配置
    • application-dev.properties:开发环境配置
  • application.properties色湖之激活哪个环境

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

yaml的多文档块

#默认激活环境
server:
   port: 8081


#选择要激活那个环境块
 
 spring:
   profiles:
     active: prod#激活哪个模块
 
 
 
 ---  #分割线
 server:
   port: 8083
 spring:
   profiles: dev #配置环境的名称
 
 
 ---
 
 server:
   port: 8084
 spring:
   profiles: prod  #配置环境的名称

5.SpringBootWeb开发总览

  • 最大特点:自动装配
  • xxxAutoConfiguration:向容器中自动配置组件
  • xxProperties:自动配置类

解决的问题

  • 导入静态资源
  • 首页
  • 写jsp的地方,模板引擎Thymeleaf
  • 装配和扩展SpringMVC
  • 增删改查
  • 拦截器

5.1静态资源处理

SpringBoot中惊天资源的位置是有规定的,在 WebMvcAutoConfiguration有体现

包的自动导入

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
    // 已禁用默认资源处理
    logger.debug("Default resource handling disabled");
    return;
}
// 缓存控制
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
// webjars 配置
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
                                     .addResourceLocations("classpath:/META-INF/resources/webjars/")
                                     .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
// 静态资源配置
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                                     .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                                     .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
  • 所有的 /webjars/** , 都需要去 classpath:/META-INF/resources/webjars/ 找对应的资源;
  • webjars,本质就是以jar导入我们的静态资源,网址查看需要的web开发需要的webjars

https://www.webjars.org

静态资源映射

我们项目中的静态资源改如何导入呢?可以存放在以下四个文件夹

  • classpath:项目所在路径
"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
  • 设置类

    // 进入方法
    public String[] getStaticLocations() {
        return this.staticLocations;
    }
    // 找到对应的值
    private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
    // 找到路径 classpath就是-> resources资源目录
    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { 
        "classpath:/META-INF/resources/",
        "classpath:/resources/", 
        "classpath:/static/", 
        "classpath:/public/" 
    };
    

6.SpringMVC自动配置原理

Springboot对SpringMVC做了哪些配置,是如何定制的呢?

6.1MVC配置

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.

ContentNegotiatingViewResolver

  • 内容协商视图解析器

  • 组合所有的视图解析器

  • 自动配置了ViewResolver(SpringMVC的视图解析器)

    也就是说可以根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染,转发,重定向

6.2格式器和转化器

  1. 找到格式转换器
@Bean
@Override
public FormattingConversionService mvcConversionService() {
    // 拿到配置文件中的格式化规则
    WebConversionService conversionService = 
        new WebConversionService(this.mvcProperties.getDateFormat());
    addFormatters(conversionService);
    return conversionService;
}
  1. 点进去

    public String getDateFormat() {
        return this.dateFormat;
    }
    /**
    * Date format to use. For instance, `dd/MM/yyyy`. 默认的
    */
    private String dateFormat;
    

可以看到在我们的Properties文件中,我们可以进行自动配置它!
如果配置了自己的格式化方式,就会注册到Bean中生效,我们可以在配置文件中配置日期格式化的规则:

spring:
  mvc:
    date-format: 

7.如何写一个web网站

前端

  • 框架:组件,需要自己手动组合拼接
    • 栅格系统
    • 导航栏
    • 侧边栏
  • 模板:使用推荐模板,别人写好的,我们拿来改成自己需要的

开发过程

  1. 分别建立前端后端项目,测试通信
  2. 设计数据库
  3. 前端独立运行
  4. 数据接口对接:json
  5. 前后端联调

8.Springboot与数据库联动

对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。
Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库,Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目。
Sping Data 官网:https://spring.io/projects/spring-data
数据库相关的启动器 :可以参考官方文档:
https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#using-boot-starter

我们主要使用MyBatisPlus,具体内容可看MybatisPlus,这里我们介绍一下其他操作

8.1整合Druid数据源

注意不支持windows系统

优势

  • 替换DBCP和C3P0,提供了一个高效,功能强大,可扩展性好的数据库连接池

  • 可以监控数据库访问性能。内置StatFilter插件,能够详细分析SQL执行性能

  • 数据库加密

  • SQL执行日志,提供了不同的LogFilter,能够支持Common-Logging,Log4j和jdkLog

    按需选择对应的LogFilter,监控应用的数据库访问情况

  • 扩展JDBC,如果有底层的编程需求,可以很方便的编写

步骤

  1. 添加依赖

    
    <dependency>
      <groupId>com.alibabagroupId>
      <artifactId>druidartifactId>
      <version>1.1.21version>
    dependency>
    
  2. 切换数据源

    spring:
       datasource:
         username: root
         password: "000000"
         driver-class-name: com.mysql.cj.jdbc.Driver
         url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&useSSL=false&useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true
         type: com.alibaba.druid.pool.DruidDataSource
    
  3. 测试类中注入DataSource,然后获取他

你可能感兴趣的:(spring,boot,后端,java)