SpringBoot整理

SpringBoot

本笔记是在学习狂神说java的B站视频记录的。

微服务阶段

JavaSE: OOP

mysql:持久化

html+css+js+jquery+框架:视图

javaweb:独立开发MVC三层架构的网站:原始

ssm:框架:简化了开发流程,配置也开始复杂

war: tomcat运行

spring再简化:SpringBoot-jar:内嵌tomcat;微服务架构!

服务越来越多:springcloud;

Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。

SpringBoot:约定大于配置

微服务架构

业务:service: userService:===> 模块!

​ springmvc,controller ===> 提供接口!

http: rpc

框架演进

微服务论文:https://martinfowler.com/articles/microservices.html

中文版:https://www.jianshu.com/p/4821a29fa998

单块应用和微服务

微服务是拆分复用,节省调用资源,各服务可替换,可升级

第一个Springboot项目

IDEA用spring Initializr生成 或者 用官网生成:https://start.spring.io/

SpringBoot自动装配原理

自动配置:

pom.xml

  • spring-boot-dependencies:核心依赖在父工程中!
  • 我们在写或引入一些Springboot依赖的时候,不需要指定版本,是因为父工程中指定了

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

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

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

我们要使用什么功能,找到对应的启动器starter就行

主程序

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

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

}
  • 注解

    @SpringBootApplication:标注这个类是一个springboot应用
      @SpringBootConfiguration:springboot的配置
          @Configuration:spring配置类
              @Component:说明这也是一个spring的组件
      @EnableAutoConfiguration:自动配置
          @AutoConfigurationPackage:自动配置包
                @Import({Registrar.class}):自动配置`包注册`
            @Import({AutoConfigurationImportSelector.class}):自动配置导入选择
      
      //获取所有的配置
      List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
    

    获取候选的配置

    protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
            List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
            Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
            return configurations;
        }
    

    META-INF/spring.factories:自动配置核心包

spring.factories位置
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
//所有资源加载到配置类中!

@ConditionOnClass: 如果条件都满足才能生效

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

  1. springboot在启动的时候,从类路径下的META-INF/spring.factories获取指定的值;
  2. 将这些自动配置的类导入容器,自动配置就会生效,帮我们进行自动配置;
  3. 以前我们需要自动配置的东西,现在springboot帮我们做了!
  4. 整合javaEE,解决方案和自动配置的东西都在spring-boot-test-autoconfigure-2.3.3.RELEASE.jar这个包下;
  5. 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
  6. 容器中也会存在非常多的xxxAutoConfiguration的文件(@Bean),就是这些类容器中导入了这个场景需要的所有组件;并自动配置,@Configuration,JavaConfig
  7. 有了自动配置类,免去了我们手动编写配置文件的工作!

参考:https://www.cnblogs.com/hellokuangshen/p/12450327.html

关于SpringBoot,谈谈你的理解:

  • 自动装配
  • run():
    • 判断应用是普通项目还是web项目
    • 判断主类加载
    • 监听器获取上下文处理Bean
    • 全面接管SpringMVC的配置
run流程

Spring配置

两种文件:application.properties或者application.yml

yaml可以直接给实体类赋值

//方法一:用这个注解将yaml中的配置和类的属性绑定
@ConfigurationProperties(prefix = "person")

//方法二:加载指定文件 用@Value映射
@PropertySource(value = "classpath:zyt.properties")
//这个使用起来并不友好,要给属性单独一个个赋值  ${}是EL表达式
@Value("${name}")
private String name;
image-20201125091400282

松散绑定:last-name可以绑定驼峰命名lastName

JSE303校验:

validated可用注解

application.yml优先级:file:./config > file:./ > classpath:/config/ > classpath:/

官方配的优先级是最低的

# 可以通过 debug=true 来查看,哪些自动配置类生效,哪些不生效
debug: true
# ---是分模块,相当于两个yml文件
---
# 配置多环境
spring:
  profiles:
    active: dev

yml里的key是跟xxxProperties类的属性对应的,被xxxAutoConfiguration装配,有默认值,所以我们可以通过yml修改配置

@Conditional派生注解

这就是自动装配的原理(精髓):

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

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

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

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

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

    xxxProperties:封装配置文件中的相关属性

SpringBoot Web开发

要解决的问题:

  • 导入静态资源
  • 首页
  • jsp,模板引擎
  • 装配扩展SpringMVC
  • 增删改查
  • 拦截器
  • 国际化

静态资源

public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (!this.resourceProperties.isAddMappings()) {
            logger.debug("Default resource handling disabled");
        } else {
            Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
            CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
            if (!registry.hasMappingForPattern("/webjars/**")) {
                this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
            }

            String staticPathPattern = this.mvcProperties.getStaticPathPattern();
            if (!registry.hasMappingForPattern(staticPathPattern)) {
                this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
            }

        }
    }

总结:

  1. 在SpringBoot,我们可以使用以下方式处理静态资源
    • webjars localhost:8080/webjars/
    • public,static,/**,resources localhost:8080/
  2. 优先级:resources > statics(默认) > public

在springboot中,有非常多的 xxx Configuration 帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了,它改变了springboot原有的东西。

前端:

  • 模板:别人写好的,我们拿来改成自己需要的
  • 框架:组件:自己手动组合拼接!Bootstrap,Layui,element-ui,semantic-ui
    • 栅格系统
    • 导航栏
    • 侧边栏
    • 表单

如何写一个网站

  1. 前端搞定:页面长什么样子:数据
  2. 设计数据库(难点)
  3. 前端让它能自动运行,独立化工程
  4. 数据接口如何对接:json,对象all in one
  5. 前后端联调
    • 有一套熟悉的后台模板:X-admin
    • 前端界面:通过前端框架组合
    • 让这个网站能够独立运行

SpringSecurity(安全)

过滤器,拦截器

安全应该在什么时候考虑?设计之初!

shiro/SpringSecurity:很像

认证(Authentication)

授权(Authorization)

  • 功能权限
  • 访问权限
  • 菜单权限

运用了AOP思想

SpringSecurity记住几个类:

  • WebSecurityConfigurerAdapter:自定义Security策略
  • AuthenticationManagerBuilder:自定义认证策略
  • @EnableWebSecurity:开启WebSecurity模式
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //链式编程
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/test").hasRole("vip");
        //没有权限默认会到登录页面
        http.formLogin()
                .loginPage("/toLogin")   //自定义登录页
                .usernameParameter("user")  //默认为username,自定义表单name = "user"
                .passwordParameter("pwd")  //默认为password,自定义表单name = "pwd"
                .loginProcessingUrl("/login");
        //防止网站工具:get,post
        http.csrf().disable();//关闭csrf功能
        //注销
        http.logout().logoutSuccessUrl("/");

        //开启记住我功能,cookie默认保存两周
        http.rememberMe()
        .rememberMeParameter("remember");//自定义表单name = "remember"
    }

    //认证 spring 2.1.x 可以直接使用
    //密码编码 passwordEncoder
    //在SpringSecurity 5+ 新增了很多加密方式
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //这原来是从数据库中取
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("zyt").password(new BCryptPasswordEncoder().encode("123456")).roles("vip");
    }
}

Swagger2

  • 号称最流行的Api框架
  • RestfulApi文档在线生成工具
  • 直接运行,可以在线测试API接口

导入依赖:


    io.springfox
    springfox-swagger2
    2.9.2


    io.springfox
    springfox-swagger-ui
    2.9.2

扫描包

//配置swagger2的Docket的bean实例
@Bean
public Docket docket() {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .select()
            //RequestHandlerSelectors:配置扫描接口的方式
            //basePackage("com.zyt.swagger.controller"):配置要扫描的包
            //withClassAnnotation(RestController.class):扫描类上的注解,参数使一个注解对象
            //withMethodAnnotation(GetMapping.class):扫描方法上的注解
            .apis(RequestHandlerSelectors.basePackage("com.zyt.swagger.controller"))
            //paths:过滤扫描路径
            .paths(PathSelectors.ant("/zyt/**"))
            .build();
}

题目:swagger在生产环境中使用,在发布的时候不使用

判断生产环境,flag=false

用enable(false)

分组 .groupName("xxx")

任务

  • 异步任务

    • @Async //告诉spring这是一个异步方法
    • @EnableAsync //开启异步注解功能
  • 邮件发送

    • spring-boot-starter-mail
  • 定时任务

    TaskScheduler 任务调度者
    TaskExecutor 任务执行者
    
    @EnableScheduling //开启定时功能的注解
    @Scheduled //在特定的时间执行这个方法
    //cron 表达式
    

redis整合

导入依赖包:spring-boot-starter-data-redis

// 用法
RedisTemplate redisTemplate;
redisTemplate.opsForValue().get();
redisTemplate.opsForValue().set();

分布式 Dobbo+zookeeper+SpringBoot

分布式系统是有一组通过网络进行通信,为了完成共同的任务而协调工作的计算机节点组成的系统。

分布式调用方法

HTTP——网络通信协议(SpringCloud生态)

RPC——远程过程调用,核心:通讯,序列化(Duddo)

image-20201207105148648

序列化:数据传输需要转换

Dubbo~ 18年重启,Java RPC框架

image-20201207110356901

(前台 中台 后台)

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

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

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

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

zookeeper:注册中心

dubbo-admin:是一个监控管理后台,用于查看我们注册了哪些服务,哪些服务被消费了。

Dubbo:jar包



    org.apache.dubbo
    dubbo-spring-boot-starter
    2.7.3


    com.github.sgroschupf
    zkclient
    0.1




    org.apache.curator
    curator-framework
    2.12.0


    org.apache.curator
    curator-recipes
    2.12.0


    org.apache.zookeeper
    zookeeper
    3.4.14
    
    
        
            org.slf4j
            slf4j-log4j12
        
    

步骤:

前提:zookeeper服务已开启

  1. 提供者提供服务
    1. 导入依赖
    2. 配置注册中心的地址,以及服务发现名,和要扫描的包
    3. 在想要被注册的服务上,增加一个注解@Service(Dubbo的)
  2. 消费者如何消费
    1. 导入依赖
    2. 配置注册中心的地址,配置自己的服务名
    3. 从远程注入服务@Reference——(跟接口名对应)

聊聊现在和未来

回顾以前,架构

三层架构 + MVC

​ 架构 ---> 解耦

开源框架

  • Spring
    • IOC AOP
    • IOC:控制反转——原来我们都是自己一步步操作,现在交给容器了!我们需要什么就去拿就可以了。
    • AOP:切面(本质,动态代理)为了解决什么?不影响业务本来的情况下,实现动态增加功能,大量应用在日志,事务……等等方面
    • 是一个轻量级的Java开源框架,容器
    • 目的:解决企业开发的复杂性问题
    • 配置文件复杂
  • SpringBoot
    • 并不是新东西,就是Spring的升级版
    • 新一代JavaEE的开发标准,开箱即用!->拿过来就可以用
    • 它自动帮我们配置了非常多的东西,我们拿来即用!
    • 特性:约定大于配置
  • 微服务架构 --->新架构
    • 模块化,功能化!
    • 用户,支付,签到,娱乐……
    • 人多:一台服务器解决不了;再增加服务器! (横向)
    • 假设A服务器占用98%资源,B服务器只占用10%;--负载均衡
    • 将原来的整体项目,分成模块化,用户就是一个单独的项目,签到也是一个单独的项目,项目和项目之间需要相互通信,如何通信?
    • 用户非常多,签到十分少!给用户多一点服务器,给签到少分点服务器

​ 微服务架构问题?

分布式架构会遇到的四个核心问题?

  1. 这么多服务,客户端该如何去访问?
  2. 这么多服务,服务之间如何进行通信?
  3. 这么多服务,如何治理呢?
  4. 服务挂了,怎么办?

解决方案:

​ SpringCloud,是一套生态,就是来解决以上分布式架构的4个问题。

​ 想使用SpringCloud,必须要掌握SpringBoot,因为SpringCloud是基于SpringBoot

  1. Spring Cloud NetFlix ,出来了一套解决方案!一站式解决方案,我们都可以直接取这里拿

    Api网关,zuul组件

    Feign --> HttpClient ---> HTTP的通信方式,同步并阻塞

    服务注册与发现,Eureka

    熔断机制,Hystrix

    2018年年底,NetFlix宣布无限期停止维护。生态不再维护,就会脱节

  2. Apache Dubbo zookeeper,第二套解决系统

    • API:没有,要么找第三方组件,要么自己实现

    • Dubbo是一个高性能的基于Java实现的RPC通信框架!2.6.x

    • 服务注册与发现,zookeeper:动物园管理者(Hadoop,Hive)

    • 没有熔断机制,借助了Hystrix

    • 不完善,Dubbo当前3.0汲取阿里内部HSF的设计长处

  3. SpringCloud Alibaba 一站式解决方案

目前,又提出了一种方案:

​ 服务网格:下一代微服务标准,Server Mesh

​ 代表解决方案:istio(未来需要掌握)

万变不离其宗,一通百通!

  1. API网关,服务路由
  2. HTTP、RPC框架,异步调用
  3. 服务注册与发现,高可用
  4. 熔断记住,服务降级

为什么要解决这个问题?本质:网络是不可靠的!

程序猿不要停下学习的脚步!

你可能感兴趣的:(SpringBoot整理)