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:自动配置核心包
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
//所有资源加载到配置类中!
@ConditionOnClass: 如果条件都满足才能生效
结论:springboot所有自动配置都在启动类中扫描并加载:spring.factories
所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!
- springboot在启动的时候,从类路径下的META-INF/spring.factories获取指定的值;
- 将这些自动配置的类导入容器,自动配置就会生效,帮我们进行自动配置;
- 以前我们需要自动配置的东西,现在springboot帮我们做了!
- 整合javaEE,解决方案和自动配置的东西都在spring-boot-test-autoconfigure-2.3.3.RELEASE.jar这个包下;
- 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
- 容器中也会存在非常多的xxxAutoConfiguration的文件(@Bean),就是这些类容器中导入了这个场景需要的所有组件;并自动配置,@Configuration,JavaConfig;
- 有了自动配置类,免去了我们手动编写配置文件的工作!
参考:https://www.cnblogs.com/hellokuangshen/p/12450327.html
关于SpringBoot,谈谈你的理解:
- 自动装配
- run():
- 判断应用是普通项目还是web项目
- 判断主类加载
- 监听器获取上下文处理Bean
- 全面接管SpringMVC的配置
Spring配置
两种文件:application.properties或者application.yml
yaml可以直接给实体类赋值
//方法一:用这个注解将yaml中的配置和类的属性绑定
@ConfigurationProperties(prefix = "person")
//方法二:加载指定文件 用@Value映射
@PropertySource(value = "classpath:zyt.properties")
//这个使用起来并不友好,要给属性单独一个个赋值 ${}是EL表达式
@Value("${name}")
private String name;
松散绑定:last-name可以绑定驼峰命名lastName
JSE303校验:
application.yml优先级:file:./config > file:./ > classpath:/config/ > classpath:/
官方配的优先级是最低的
# 可以通过 debug=true 来查看,哪些自动配置类生效,哪些不生效
debug: true
# ---是分模块,相当于两个yml文件
---
# 配置多环境
spring:
profiles:
active: dev
yml里的key是跟xxxProperties类的属性对应的,被xxxAutoConfiguration装配,有默认值,所以我们可以通过yml修改配置
这就是自动装配的原理(精髓):
SpringBoot启动会加载大量的自动配置类;
我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
我们再来看这个自动配置类中到底配置了哪些组件(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
-
给容器中自动配置类添加组件的时候,会从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));
}
}
}
总结:
- 在SpringBoot,我们可以使用以下方式处理静态资源
- webjars
localhost:8080/webjars/
- public,static,/**,resources
localhost:8080/
- webjars
- 优先级:resources > statics(默认) > public
在springboot中,有非常多的 xxx Configuration 帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了,它改变了springboot原有的东西。
前端:
- 模板:别人写好的,我们拿来改成自己需要的
- 框架:组件:自己手动组合拼接!Bootstrap,Layui,element-ui,semantic-ui
- 栅格系统
- 导航栏
- 侧边栏
- 表单
如何写一个网站
- 前端搞定:页面长什么样子:数据
- 设计数据库(难点)
- 前端让它能自动运行,独立化工程
- 数据接口如何对接:json,对象all in one
- 前后端联调
- 有一套熟悉的后台模板: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)
序列化:数据传输需要转换
Dubbo~ 18年重启,Java RPC框架
(前台 中台 后台)
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服务已开启
- 提供者提供服务
- 导入依赖
- 配置注册中心的地址,以及服务发现名,和要扫描的包
- 在想要被注册的服务上,增加一个注解@Service(Dubbo的)
- 消费者如何消费
- 导入依赖
- 配置注册中心的地址,配置自己的服务名
- 从远程注入服务@Reference——(跟接口名对应)
聊聊现在和未来
回顾以前,架构
三层架构 + MVC
架构 ---> 解耦
开源框架
- Spring
- IOC AOP
- IOC:控制反转——原来我们都是自己一步步操作,现在交给容器了!我们需要什么就去拿就可以了。
- AOP:切面(本质,动态代理)为了解决什么?不影响业务本来的情况下,实现动态增加功能,大量应用在日志,事务……等等方面
- 是一个轻量级的Java开源框架,容器
- 目的:解决企业开发的复杂性问题
- 配置文件复杂
- SpringBoot
- 并不是新东西,就是Spring的升级版
- 新一代JavaEE的开发标准,开箱即用!->拿过来就可以用
- 它自动帮我们配置了非常多的东西,我们拿来即用!
- 特性:约定大于配置
- 微服务架构 --->新架构
- 模块化,功能化!
- 用户,支付,签到,娱乐……
- 人多:一台服务器解决不了;再增加服务器! (横向)
- 假设A服务器占用98%资源,B服务器只占用10%;--负载均衡
- 将原来的整体项目,分成模块化,用户就是一个单独的项目,签到也是一个单独的项目,项目和项目之间需要相互通信,如何通信?
- 用户非常多,签到十分少!给用户多一点服务器,给签到少分点服务器
微服务架构问题?
分布式架构会遇到的四个核心问题?
- 这么多服务,客户端该如何去访问?
- 这么多服务,服务之间如何进行通信?
- 这么多服务,如何治理呢?
- 服务挂了,怎么办?
解决方案:
SpringCloud,是一套生态,就是来解决以上分布式架构的4个问题。
想使用SpringCloud,必须要掌握SpringBoot,因为SpringCloud是基于SpringBoot
-
Spring Cloud NetFlix ,出来了一套解决方案!一站式解决方案,我们都可以直接取这里拿
Api网关,zuul组件
Feign --> HttpClient ---> HTTP的通信方式,同步并阻塞
服务注册与发现,Eureka
熔断机制,Hystrix
2018年年底,NetFlix宣布无限期停止维护。生态不再维护,就会脱节
-
Apache Dubbo zookeeper,第二套解决系统
API:没有,要么找第三方组件,要么自己实现
Dubbo是一个高性能的基于Java实现的RPC通信框架!2.6.x
服务注册与发现,zookeeper:动物园管理者(Hadoop,Hive)
没有熔断机制,借助了Hystrix
不完善,Dubbo当前3.0汲取阿里内部HSF的设计长处
SpringCloud Alibaba 一站式解决方案
目前,又提出了一种方案:
服务网格:下一代微服务标准,Server Mesh
代表解决方案:istio(未来需要掌握)
万变不离其宗,一通百通!
- API网关,服务路由
- HTTP、RPC框架,异步调用
- 服务注册与发现,高可用
- 熔断记住,服务降级
为什么要解决这个问题?本质:网络是不可靠的!
程序猿不要停下学习的脚步!