文章目录
前言
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