Spring Boot 总结

前言

1.什么是SpringBoot?

基于Spring开发。简化了Spring的配置
核心思想:约定大于配置


2.什么是微服务架构?

在这里插入图片描述

1)什么是微服务?

一种架构风格,要求在开发一个应用的时候,必须要构建成一系列小服务的组合,通过http的方式进行互通

2)单体应用架构(ORM)

在这里插入图片描述

将一个应用中的所有应用服务都封装在一个应用中

缺点:
1、性能拓展性差
2、无法协同开发
3、不利于升级维护

3)垂直应用架构(MVC)

在这里插入图片描述

将互不相关的应用拆开,提升效率

缺点:公共模块无法重复利用,开发性的浪费

4)分布式服务架构(RPC)

在这里插入图片描述

建议参考这一篇博客。点此跳转
在MVC的基础上,提取出核心业务作为独立的服务

5)流动计算架构(SOA:Service Oriented Architecture)

在这里插入图片描述
当服务越来越多后,需要增加一个 调度中心 基于访问压力实时管理集群容量,提高集群利用率


一、第一个Springboot项目

1.创建项目

1、在Spring官网上搭建。点此跳转
在这里插入图片描述

2、在idea上创建(idea集成了这个网站)
在这里插入图片描述
在这里插入图片描述
tips:如果无法创建,原因在于Spring Initializr的构建依赖于国外的服务器,有时候会出现不稳定而造成无法创建Spring Initializr,可以将服务器的地址设置为阿里云的服务器地址:https://start.aliyun.com/
在这里插入图片描述

3、创建好的项目格式
在这里插入图片描述

4、创建一个业务
在这里插入图片描述

在这里插入图片描述

2.拓展

1)更改项目的端口号

在这里插入图片描述

2)热部署

我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大量的时间。

在 springboot 中修改代码后不重启就能生效,由于Spring Boot应用只是普通的Java应用,所以JVM热部署(hot-swapping)也能开箱即用。不过JVM热部署能替换的字节码有限制,想要更彻底的解决方案可以使用Spring Loaded项目或JRebel。 spring-boot-devtools 模块也支持应用快速重启(restart)。


二、Springboot 自动装配

1.基本组件

1)pom.xml

  • 在父工程中存放了大量的核心依赖,所以在写springboot依赖的时候,不需要指定版本
    在这里插入图片描述

2)启动器

  • 可以理解成 springboot 的启动场景
    比如说 spring-boot-starter-web ,会自动导入web环境所有的依赖
  • springboot 会将所有的功能场景都变成启动器,根据所需要的功能找到对应的启动器即可

在这里插入图片描述


2.@SpringBootApplication

标注这个注解所修饰的类是一个 springboot 的应用
在这里插入图片描述


1)@SpringBootConfiguration

springboot 的配置注解

在这里插入图片描述
在这里插入图片描述


2)@EnableAutoConfiguration

自动配置

在这里插入图片描述

1>@AutoConfigurationPackage

自动配置包
在这里插入图片描述

– @Import({Registrar.class})

导入Registrar.class

– Registrar.class
2>@Import({AutoConfigurationImportSelector.class})

导入AutoConfigurationImportSelector.class
在这里插入图片描述

– AutoConfigurationImportSelector.class

1)public String[] selectImports(AnnotationMetadata annotationMetadata) {}
选择组件
在这里插入图片描述

2)protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata){}
获取所有自动配置项
在这里插入图片描述

3)public static List loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader)
获取 META-INF/spring.factories 中的资源
在这里插入图片描述

4)META-INF/spring.factories
在这里插入图片描述

3)@ConditionOnXXX

为什么有的配置存在于 META-INF/spring.factories 中,但仍需要在 pom.xml 文件中配置启动器才能生效?
在这里插入图片描述


4)结论

1、springboot 所有的自动配置都是在启动的时候扫描并加载。
2、这些自动配置类都在 META-INF/spring.factories 中。
3、这些自动配置类不一定生效,因为被 @ConditionOnXXX 注解修饰,需要判断条件是否成立
4、springboot 帮助我们省去了手动加载配置类的过程


3.主启动类

开启了一个服务
在这里插入图片描述

1)SpringApplication的实例化

1、推断应用的类型是普通的项目还是Web项目
2、查找并加载所有可用的初始化器,设置到 initializers 属性中
3、找出所有的应用程序监听器,设置到 listeners 属性中
在这里插入图片描述
4、推断并设置方法的定义类,找到运行的主类
在这里插入图片描述

2)执行 run()

通过run() 中的监听器获取 ApplicationContext(应用上下文), 处理bean


4.配置文件

1)yaml文件

在这里插入图片描述

2)特点

1、可以注入到配置类中
在这里插入图片描述

2、比较

特点@ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持
  • 松散绑定:yaml 文件中写的last-name,等价于 lastName,- 后面跟着的字母默认是大写的
  • JSR303数据校验:可以在字段前增加一层过滤器验证,可以保证数据的合法性

3)自动配置原理
如果我们需要的功能在 springboot 默认的自动配置类中没有,可以通过 yaml 配置文件来新增
xxxxAutoConfiguration:自动配置类,给容器中添加对应的组件
xxxxProperties:封装配置文件中相关属性


三、SpringSecurity

1.简介

针对Spring项目的安全框架,是 SpringBoot 底层安全模块默认的技术选型
认证(Authentication)
授权(Authorization),官网上是 访问控制(Access-Control)


2.认证与授权

在这里插入图片描述


3.登出

在这里插入图片描述


3.记住我

在这里插入图片描述


四、Shiro

1.简介

  • Apache Shiro 是一个Java的安全(权限)框架
  • 可以完成 认证、授权、加密、会话管理、Web继承、缓存
  • 下载地址:https://shiro.apache.org/
  • Shiro架构在这里插入图片描述

2.源码解析

1、大体框架

// 获取当前的用户对象
Subject currentUser = SecurityUtils.getSubject();

// 通过当前用户拿到 session,并且通过session进行存值或取值
Session session = currentUser.getSession();

// 判断当前的用户是否被认证
currentUser.isAuthenticated()
// 获得当前用户的认证
currentUser.getPrincipal()

// 当前用户有什么角色
currentUser.hasRole("schwartz")

// 当前用户有什么权限
currentUser.isPermitted("lightsaber:wield")

// 注销
currentUser.logout()

2、源码

public class Quickstart {

    private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);


    public static void main(String[] args) {

        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);

        // 获取当前的用户对象
        Subject currentUser = SecurityUtils.getSubject();

        // 通过当前用户拿到 session,并且通过session进行存值或取值
        Session session = currentUser.getSession();
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("Retrieved the correct value! [" + value + "]");
        }

        // 判断当前的用户是否被认证
        if (!currentUser.isAuthenticated()) {
            // Token:令牌
            // 通过用户的账户和密码生成一个令牌
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            // 设置记住我
            token.setRememberMe(true);
            try {
                currentUser.login(token);   //执行登录操作
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
                //unexpected condition?  error?
            }
        }

        //say who they are:
        //print their identifying principal (in this case, a username):
        log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");

        //test a role:
        if (currentUser.hasRole("schwartz")) {
            log.info("May the Schwartz be with you!");
        } else {
            log.info("Hello, mere mortal.");
        }

        // 粗粒度
        //test a typed permission (not instance-level)
        if (currentUser.isPermitted("lightsaber:wield")) {
            log.info("You may use a lightsaber ring.  Use it wisely.");
        } else {
            log.info("Sorry, lightsaber rings are for schwartz masters only.");
        }

        // 细粒度
        //a (very powerful) Instance Level permission:
        if (currentUser.isPermitted("winnebago:drive:eagle5")) {
            log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                    "Here are the keys - have fun!");
        } else {
            log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
        }

        //all done - log out!
        currentUser.logout();

        System.exit(0);
    }
}

3.搭建Shiro

1、整体框架
在这里插入图片描述

2、创建 realm 对象
在这里插入图片描述

3、DefaultWebSecurityManager
在这里插入图片描述

4、ShiroFilterFactoryBean
在这里插入图片描述

4.Shiro实现登录拦截

在这里插入图片描述

5.Shiro实现认证

1、一般在Controller中

@RequestMapping("/login")
public String login(String username, String password) {
    // 获取当前用户
    Subject subject = SecurityUtils.getSubject();

    // 封装用户的登录数据
    UsernamePasswordToken token = new UsernamePasswordToken(username, password);

    subject.login(token);
    return "index";
}

2、认证功能
在这里插入图片描述

6.Shiro实现授权

未授权会报 401 错误
1、添加授权功能
在这里插入图片描述

2、给用户授权
在这里插入图片描述


五、Swagger

API框架,可以实时更新api


六、分布式系统

1.理论

分布式系统是建立在网络之上的软件系统,是若干独立计算机的集合,这些计算机对于用户来说就像是单个相关系统
详情可参考本文简介内容


2.RPC协议(Remote Procedure Call)

远程过程调用,进程间的一种通信协议

  • http
    无状态通信协议,负责基于网络的通信
  • 本地调用
    在一台电脑上,A() 调用 B()
  • 远程调用
    在a电脑上的A(),调用b电脑上的B()
    分布式系统会产生一些问题,源自于网络不可靠
  • 核心模块:通讯、序列化(方便数据传输)

3.Dubbo

1)简介

官网链接:https://dubbo.apache.org/zh/
是一款高性能、轻量级的Java RPC框架
在这里插入图片描述

2)zookeeper 注册中心下载与安装

官方文档链接:https://dubbo.apache.org/zh/docs/references/registry/zookeeper/
点此下载:https://mirror.bit.edu.cn/apache/zookeeper/
在这里插入图片描述

  • 第一步:启动服务端在这里插入图片描述

如果闪退,打开此文件编辑,添加一个pause,用来看报错信息
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 第二步:启动客户端(必须同时开启服务端)
    默认端口号是 2181
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值