InterV 4:分布式系统微服务
一、架构设计相关
0. 什么是微服务?什么是分布式系统?什么是集群?
微服务:构建分布式系统的一种架构方式, 核心思路是:去中心化。
分布式系统: 一件事情,多系统协同完成。
集群:多机器做同一件事情。
比如在淘宝买东西,会有一个商品展示的系统,看到合适的商品了就会下单这是会有一个订单系统,下单完成了就进入发货阶段,这个时候就会有一个物流系统,买东西就形成了一个分布式系统,而每个系统又由多个微服务组成,所以微服务是构建分布式系统的一种架构方式,当买东西的人多了,系统就会出现慢的现象,这个时候就需要把每个系统里面的微服务多部署几台机器来承载更多的请求,这样就形成了集群。
1. RPC和RPC框架
RPC:远程过程调用,实现远程过程调用的方式有很多种,Dubbo,Rmi,Hessian等等;
RPC的核心过程包括了客户端和服务端的通讯协议,寻址,数据序列化/反序列化;
RPC框架:实现远程过程调用方式的组件,不需要开发人员自己去定义通讯协议,去实现序列化的细节工作
常见RPC框架有 thrift,gRpc,dubbo,motan
2. 序列化方式及作用
序列化:将java对象或者其他内存中的数据,转换为一种可以在网络上传输和可以在磁盘上存储的格式(流)的数据。
反序列化:将可以在网络上传输和可以在磁盘上存储的格式(流)的数据转为java对象或者内存中其他形式的数据。
序列化方式: json,jdk serializable, Hessian,Dubbo, Protobuf。
序列化的作用:压缩、持久化存储、跨网络传输。
3. 分布式系统中事务的处理
3.1 事务相关必了解的概念:
3.1.1 ACID (Atomic原子性,Consistency一致性,Isolation隔离性,Durability持久性)
A是原子性(atomic):事务中包含的各项操作必须全部成功执行或者全部不执行。任何一项操作失败,将导致整个事务失败,其他已经执行的任务所做的数据操作都将被撤销,只有所有的操作全部成功,整个事务才算是成功完成。
C是一致性(consistent):保证了当事务结束后,系统状态是一致的。那么什么是一致的系统状态?例如,如果银行始终遵循着"银行账号必须保持正态平衡"的原则,那么银行系统的状态就是一致的。上面的转账例子中,在取钱的过程中,账户会出现负态平衡,在事务结束之后,系统又回到一致的状态。这样,系统的状态对于客户来说,始终是一致的。
I是隔离性(isolated):并发执行的事务,彼此无法看到对方的中间状态。保证了并发执行的事务顺序执行,而不会导致系统状态不一致。
D是持久性(durable):保证了事务完成后所作的改动,即使是发生灾难性的失败都会被持久化。可恢复性资源保存了一份事务日志,如果资源发生故障,可以通过日志来将数据重建起来
3.1.2 CAP理论 (一致性Consistency,可用性Availability,分区容错性Partition tolerance),分布式系统来说,P是不能放弃的
C(Consistency)一致性:分布式数据库的数据保持一致
A(Availability)可用性:任何一个节点挂了,其他节点可以继续对外提供服务
P(Partition tolerance)分区容错性(网络分区):一个数据库所在的机器坏了,如硬盘坏了,数据丢失了,可以新增一台机器,然后从其他正常的机器把备份的数据同步过来
CAP理论的特点:CAP只能满足其中2条
CA(放弃P):将所有的数据放在一个节点。满足一致性、可用性。
AP(放弃C):放弃强一致性,用最终一致性来保证。
CP(放弃A):一旦系统遇见故障,受到影响的服务器需要等待一段时间,在恢复期间无法对外提供服务。
举例说明CAP理论:
有3台机器,分别有3个数据库、有两张表,数据都是一样的
Machine1-db1-tbl_person、tbl_order
Machine2-db2-tbl_person、tbl_order
Machine3-db3-tbl_person、tbl_order
1)当向machine1的db1的表tbl_person、tbl_order插入数数据时,同时要把插入的数据同步到machine2、machine3,这就是一致性
2)当其中的一台机器宕机了,可以继续对外提供服务,把宕机的机器重新启动起来可以继续服务,这就是可用性
3)当machine1的机器坏了,数据全部丢失了,不会有任何问题,因为machine2和machine3上还有数据,重新加一台机器machine4,把machine2和machine3其中一台机器的备份数据同步过来就可以了,这就是分区容错性
3.1.3 BASE 理论(Basically Available(基本可用),Soft state(软状态),Eventually Consistent(最终一致性))
BA(Basically Available)基本可用:在分布式系统出现故障时,允许损失部分可用性(服务降级、页面降级)。比如系统挂了,在页面上给个提示啥的
S(Soft state)软状态:允许分布式系统出现中间状态。而且中间状态不影响系统的可用性。
这里的中间状态是指不同的数据复制data replication之间的数据更新可以出现延时的最终一致性。如CAP理论里面的示例,当向machine1的db1的表tbl_person、tbl_order插入数数据时,同时要把插入的数据同步到machine2、machine3,当machine3的网络有问题时,同步失败,但是过一会网络恢复了就同步成功了,这个同步失败的状态就称为软状态,因为最终还是同步成功了。
E(Eventually Consistent)最终一致性:数据复制data replications经过一段时间达到一致性。
3.2 分布式事务实现方式:
1. XA (数据库厂商实现);
2. 后台任务定期校对数据;
3. 通过消息队列,实现最终一致(确保消息到达MQ,幂等性);
4. TCC机制(Try,Confirm,Cancel)
补偿事务(TCC)
TCC 其实就是采用的补偿机制,核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:
-
Try 阶段主要是对业务系统做检测及资源预留
-
Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
-
Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。
示例1:假入 Bob 要向 Smith 转账
思路大概是:
我们有一个本地方法,里面依次调用
1、首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。
2、在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。
3、如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。
优点: 跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些
缺点: 缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
参考文章:
聊聊分布式事务,再说说解决方案:https://www.cnblogs.com/savorboard/p/distributed-system-transaction-consistency.html
示例2:餐馆或者KTV的预定、付款、取消
Try 预定
Confirm 付款
Cancel 取消
4. 系统监控
# 链路监控
Spring‐Cloud‐Sleuth + Zipkin
Sleuth收集微服务之间的接口调用信息以及内部方法调用。通过采样之后,将数据传输致Zipkin,由Zipkin负责存储和可视化查询;
# 核心概念:Trace,Span。公开课有讲过Sleuth;
Sleuth 是一种提供的跟踪服务,也就是说利用 sleuth 技术可以实现完整的微服务的访问路径的跟踪操作
在 SpringCloud 之中提供的 Sleuth 技术就可以实现微服务的调用跟踪,也就是说它可以自动的形成一个调用连接线,通过这个连接线使得开发者可以轻松的找到所有微服务间关系,同时也可以获取微服务所耗费的时间, 这样就可以进行微服务调用状态的监控以及相应的数据分析。
Span 里面包含有如下内容:
· cs-Client Sent:客户端发出一个请求,描述的是一个 Span 开始;
· sr-Server Received:服务端接收请求,利用 sr-cs 就属于发送的网络延迟;
· ss-Server Sent:服务端发送请求(回应处理),ss-sr 就属于服务端的消耗时间;
· cr-Client Received:客户端接收到服务端数据,cr-ss 就表示回复所需要的时间。
# 日志监控
ELK
1)ElasticSearch搜索服务器,提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。
2)Logstash是可以对日志进行收集、过滤、分析,并将其存储供以后使用;
3)Kibana 是Elasticsearch前端展示工具,可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志
搭建方式参考资料: https://www.cnblogs.com/kevingrace/p/5919021.html
# 代码性能监控
Metrics:度量;我们需要为某个系统某个服务做监控、做统计,就需要用到Metrics;代码执行的吞吐量,响应时间,并发量,瞬时状态值。
# 这个需要通过代码埋点实现,公开课有讲过Metrics+Grafana构建性能监控平台;
5. 高可用
服务的高可用可以通过多实例,自检测,自恢复,快速扩容机制来实现;
多实例:一个服务部署多个实例,通过负载均衡机制降低单实例的负载以及实现容错;
自检测:系统预留健康检查接口,通过docker集群模式的健康检查机制来实现自动重启和预警;
自恢复:对于网络抖动的问题,需要程序有一定的容错性,比如:熔断机制,Eureka的自我保护措施;
快速扩容:互联网应用的特殊性,在特定时候会出现高峰期的海量请求,此时,需要我们的分布式系统能够快速扩容。docker的服务编排就可以实现已有硬件资源的情况下秒扩容;
对于硬件资源,需要结合云计算技术来实现;
6. 服务调用的负载均衡
# 服务端负载均衡:
对客户端屏蔽具体的接口地址,对外仅暴露负载均衡器,所有请求经过统一的负载服务;有硬件负载(f5,radware)和软件负载(nginx,apache,lvs)
优势:屏蔽了微服务地址多变的复杂性,统一管理,控制;对外部调用友好;
劣势:性能要求高,流量大对负载服务本身有很高的要求;管理复杂,大多数服务端负载器需要手工配置服务实例信息;
# 客户端负载均衡:
由客户端自己选择目标服务器,直调对应的地址;dubbo(源码参考com.alibaba.dubbo.rpc.cluster.LoadBalance),springcloud(ribbon)都是客户端负载均衡;
优势:性能好,可以根据具体应用微调负载策略;易管理,服务实例信息自发现
劣势:服务实例信息在多客户端之间的不同步;通常是集群内部使用;
7. 分布式配置中心
类似产品有很多:360 Qconf,百度 Disconf,淘宝 Diamond
参考:https://www.cnblogs.com/zhangxh20/p/5464103.html
我们着重讲了springcloudconfig分布式配置中心,用来解决多配置的问题;将配置文件统一存储在gitlab,svn,filesystem,并支持敏感信息的加密存储(configserver或者client均可解密)
现在可以思考一个问题:在一个实际的项目开发过程之中,有可能会出现有上百个微服务(创建微服务的标准实际上就是业务设计,也就是说你有多少个业务接口那么就有可能需要定义有多少个的微服务,而且不要忘记了,微服务还会存在有负载均衡的问题),那么这样一来对于配置文件的管理就非常麻烦了。
如果现在要想进行某一个微服务的配置文件的变更,那么就有可能需要去修改上百个微服务的信息。所以为了解决这些配置文件的统一的管理问题,那么在 SpringCloud 架构里面提出有一个思想,借助于:SVN、GITHUB 来进行微服务配置文件的保存。
实现原理:所有微服务的配置文件放在git仓库里面,建立一个SpringCloudConfig的微服务并添加git仓库的配置,这样就能实时获取git仓库里面的配置文件了,其他的微服务就追加SpringCloudConfig的微服务的配置就能通过SpringCloudConfig的微服务获取到各自的配置文件了
但是在此时也需要注意几个问题:
· 一旦使用了 SpringCloudConfig 之中,现在的项目的中心就变为了 SpringCloudConfig 服务;
· 为了解决配置文件的安全问题,在 SpringCloudConfig 之中还提供有一个所谓的安全加密处理,例如:一些重要的密码有可能需要被加密,所以可以使用两种加密处理(密钥处理、jks 安全处理)。
8. 服务注册与发现机制
这种机制目的是实现:服务提供者的自注册,服务消费者的主动发现服务提供者;
服务注册:服务提供者启动实例时,将信息存储到注册中心;
注册中心:保存服务提供者或者消费者的实例信息(服务名称,IP,端口,方法地址等等)
服务发现:服务消费者,通过服务名在注册中心的信息中查询出具体的服务提供者实例信息。
9. 分布式系统如何拆分?
业务线(订单系统,积分系统,审计系统,支付系统,结算系统,推广系统….)
技术栈(php,java,nodejs,go)
架构分层 (前台,中台,后台; 存储服务,缓存服务,MQ服务,搜索引擎服务….)
前台:页面相关技术如node.js、网关
中台:APP注册时除了调用后台的增加功能以外还会发优惠卷,PC网站注册时除了调用后台的增加功能以外还会发送积分。这样的服务称为中台
后台:增删改查
二、SpringCloud
1. 微服务是如何保护自己的
信息加密:
通过Https实现信息传输的加密(nginx,tomcat都可以配置https);
对代码侵入性很小。因为微服务集群不直接对外提供服务,由统一的网关来提供业务API(zuul,nginx都可以的)。
权限校验方案:
单点登录:
什么是单点登录:一个系统登录以后,其他系统不需要再次登录
# 每个应用都必须接入单点登录,大型系统中,需要集成单点登录带来的复杂工作和性能损耗;
分布式session方案:
流程: 客户端 ‐> 获取session ‐> 请求微服务 ‐> 查询共享存储中授权信息 ‐> 校验权限 ‐> 提供服务 ‐> 给予响应
分布式session保存方案,根据session去查找共享存储中对应的权限信息来实现权限校验;
# 共享存储的高可用和安全性是个问题,类似直接redis,memcache来做;
token方案:
1. 客户端 ‐> uaa认证 ‐> 获取token
2. 客户端 ‐> 微服务 ‐> 校验token
token包含必要的授权信息,一次获取,多次使用,相对独立,实现简单,不需要cookie;
长度有限,不能撤销,需要设置过期时间;
# 可以在网关层做;也可以构建成通用的组件,放在每个微服务上面去做;
# 根据不同的业务场景:token可以发放一次,也可以在每次请求的时候去申请,这样能够实现分控需要的账户禁用,黑名单等功能
2. 微服务网关
在很多的开发之中为了规范微服务的使用,提供有一个路由的处理控制组件:Zuul,也就是说 Zuul 就作为中间的一个代理层出现
zuul是springcloud提供的成熟的路由方案;根据请求的路径不同,网关会定位到指定的微服务,并代理请求到不同的微服务接口;对外屏蔽了微服务接口调用的复杂性。
三个重要概念:动态路由表,路由定位,反向代理
反向代理:客户端请求到网关,网关受理后,再对目标服务发起请求,拿到响应之后,再响应给客户端;
动态路由表:zuul支持eureka路由,手动配置的路由,这两种都支持动态更新;
路由定位:根据请求路径,zuul有一套自身的服务定位规则以及路由匹配的表达式;
# 应用场景: 对外暴露,权限校验,服务聚合,日志审计
3. 各服务之间如何调用
服务对外以http接口形式暴露,所以调用有多种方式;
Fegin是cloud提供的一种服务调用客户端;
Resttemplate也可以快速的发起服务调用;
同时,也可以手动获取对应接口的具体地址,通过平常的httpclient进行调用;
# Feign和Resttemplate 都可以集成负载均衡,失败重试,熔断的功能;
4. 如何保证服务健康的情况
1.spring-boot-starter-actuator可以用来监控我们的项目,可以通过HealthEndPoint/health来查看应用的健康状况;SpringBoot在集成很多组件时,都会实现一个健康检查的接口,如ElasticsearchHealthIndicator,RedisHealthIndicator, RabbitHealthIndicator等。
2. 在微服务集群中,我们通常还会通过sleuth来进行服务调用的链路追踪,可以通过抽样看到服务调用的异常情况;
3. 日志信息也是我们监控服务监控情况的一个重要手段,常用通过ELK实现日志收集,分析和查看;
4. 在通过docker部署微服务时,我们可以利用docker的健康检查机制,实现服务的自动重启;
5. 容错机制
# Ribbon 负载均衡&重试
通过服务名获取实例信息,根据负载策略选择合适的实例去访问;
服务调用失败时,可以配置重试次数,以及实例切换的次数;
Ribbon 是一个服务调用的组件,并且是一个客户端实现负载均衡处理的组件。服务器端实现负载均衡可以使用 Nginx、 HAProxy、LVS 等。
# Hystrix熔断机制
限流,降级,熔断;
限流:限制接口访问并发量,限制缓冲区大小,超出限制,调用Fallback方法
熔断:出错率超过阈值,一定时间内不再请求该接口。(超时、run方法抛出异常)
降级:凡是没有正常的从接口中拿到数据,就会调用Fallback方法,获取一个结果
# 通过命令模式的封装,SpringCloud内部自动集成,且可作用于任意JAVA方法上,不关
心方法的具体实现。代表着(http、redis、db操作都可以做熔断);
所谓的熔断机制和日常生活中见到电路保险丝是非常相似的,当出现了问题之后,保险丝会自动烧断,以保护我们的电器, 那么如果换到了程序之中呢?
当现在服务的提供方出现了问题之后整个的程序将出现错误的信息显示,而这个时候如果不想出现这样的错误信息,而希望替换为一个错误时的内容。
一个服务挂了后续的服务跟着不能用了,这就是雪崩效应
对于熔断技术的实现需要考虑以下几种情况:
· 出现错误之后可以 fallback 错误的处理信息;
· 如果要结合 Feign 一起使用的时候还需要在 Feign(客户端)进行熔断的配置。
6. SpringCloud中的服务注册与发现机制
两个角色eurekaServer, eurekaClient
server提供httpapi服务,存储服务实例的信息,并且具备主动剔除服务(心跳检测)和server高可用的功能;
client集成在具体的微服务中,在服务启动时,将服务实例信息post到server上;client也会定时同步server上面其他service信息;
# eureka的工作大多是后台thread在定时工作,任务执行的间隔时间都可以通过配置文件进行配置;
7. SpringCloud的实施推广
# 集成SpringMVC项目
微服务改造的过渡期,在传统的SpringMvc项目中,引入部分SpringCloud的特性,即可通过微改造变成微服务;
# 其他语言的项目加入SpringCloud微服务系统
Eureka提供HttpApi,使得非java语言加入到SpringCloud微服务集群成为可能;
三、Dubbo
1. 如果注册中心集群都挂掉,发布者和订阅者之间还能通信么?
# 能,因为有缓存;
注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
新的服务将无法发现;服务下架后仍旧有被调用的可能;
2. dubbo连接注册中心和直连的区别
连接注册中心: 消费者动态发现服务提供者,实现软负载均衡和集群容错;
直连:不能动态增减提供者;开发、测试环境可通过指定Url方式绕过注册中心直连指定的服务地址,快速测试;
3. dubbo服务的容错机制
# http://dubbo.io/books/dubbo‐user‐book/demos/fault‐tolerent‐strategy.html
Failover Cluster:失败自动切换,当出现失败,重试其它服务器,默认两次;
Failfast Cluster:失败立即报错
Failsafe Cluster:失败安全,出现异常时,直接忽略
Failback Cluster:失败自动恢复,后台记录失败请求,定时重发
Forking Cluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源
Broadcast Cluster:播调用所有提供者,逐个调用,任意一台报错则报错
# 要注意分布式事务
3.1 Failover Cluster
失败自动切换,缺省值,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。
配置如下:
生产者:
<dubbo:service retries="2" />
消费者:
<dubbo:reference retries="2" />
消费者具体到调用生产者的哪个方法:
<dubbo:reference>
<dubbo:method name="findFoo" retries="2" />
</dubbo:reference>
3.2 Failfast Cluster
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
配置如下:
生产者:
<dubbo:service cluster="failfast" />
消费者:
<dubbo:reference cluster="failfast" />
3.3 Failsafe Cluster
失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
配置如下:
生产者:
<dubbo:service cluster="failsafe" />
消费者:
<dubbo:reference cluster="failsafe" />
3.4 Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
配置如下:
生产者:
<dubbo:service cluster="failback" />
消费者:
<dubbo:reference cluster="failback" />
3.5 Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。
配置如下:
生产者:
<dubbo:service cluster=“forking" />
消费者:
<dubbo:reference cluster=“forking" />
3.6 Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错 。通常用于通知所有提供者更新缓存或日志等本地资源信息。
配置如下:
生产者:
<dubbo:service cluster="broadcast" />
消费者:
<dubbo:reference cluster="broadcast" />
4. 具体问题示例1:关于服务调用超时
# 超时是针对消费端还是服务端?
dubbo的超时是争对客户端的,由于是一种NIO模式,消费端发起请求后得到一个ResponseFuture,然后消费端一直轮询这个ResponseFuture直至超时或者收到服务端的返回结果。虽然超时了,但仅仅是消费端不再等待服务端的反馈并不代表此时服务端也停止了执行。
# 超时在哪设置?
消费端
- 全局控制
<dubbo:consumer timeout="1000"></dubbo:consumer>
- 接口控制
- 方法控制
服务端
- 全局控制
<dubbo:provider timeout="1000"></dubbo:provider>
- 接口控制
- 方法控制
可以看到dubbo针对超时做了比较精细化的支持,无论是消费端还是服务端,无论是接口级别还是方法级别都有支持。
#优先级是什么?
优先顺序为:客户端方法级>服务端方法级>客户端接口级>服务端接口级>客户端全局>服务端全局
# 实现原理
消费端发起远程请求后,线程不会阻塞等待服务端的返回,而是马上得到一个ResponseFuture(ReponseFuture的实现类:DefaultFuture),消费端通过不断的轮询机制判断结果是否有返回。因为是通过轮询,轮询有个需要特别注要的就是避免死循环,所以为了解决这个问题就引入了超时机制,只在一定时间范围内做轮询,如果超时时间就返回超时异常
#设置超时主要是解决什么问题?如果没有超时机制会怎么样?
对调用的服务设置超时时间,是为了避免因为某种原因导致线程被长时间占用,最终出现线程池用完返回拒绝服务的异常。
5. 服务提供者能实现失效踢出是什么原理
服务失效踢出基于zookeeper的临时节点原理。
临时节点的生命周期和客户端会话绑定,也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉
源码参考 RegistryService, 文档参考https://www.jianshu.com/p/f42c69e4bd3e?fromApp=1
# redis ‐ 脏数据由监控中心删除
# zookeeper ‐ 的临时节点
6. dubbo通讯协议
# 什么是通讯协议
客户端服务端之间进行数据流转的一种约定,将数据按照标准格式来组装;
# 协议内容
头部信息(调用控制协议16B) + body(序列化)
head = 魔数(2) + 标识(1) + 响应状态(1) + 消息ID(8) + 内容长度(4)
body = dubbo版本 + 服务接口路径 + 服务版本号 + 服务方法名 + 参数描述符 + 参数值序列化 + 隐式参数
7. 大概率的问题
# dubbo文档,仔细阅读一遍,面试官可能随便抽取一个。
7.1 dubbo配置的方式和属性
dubbo的官网入门使用demo
1. 服务提供者
1.1 定义服务接口DemoService.java
package com.alibaba.dubbo.demo; public interface DemoService { String sayHello(String name); }
1.2 在服务提供方实现接口DemoServiceImpl.java
package com.alibaba.dubbo.demo.provider; import com.alibaba.dubbo.demo.DemoService; public class DemoServiceImpl implements DemoService { public String sayHello(String name) { return "Hello " + name; } }
1.3 用Spring配置声明暴露服务provider.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 提供方应用信息,用于计算依赖关系 --> <dubbo:application name="hello-world-app" /> <!-- 使用multicast广播注册中心暴露服务地址 --> <dubbo:registry address="multicast://224.5.6.7:1234" /> <!-- 用dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 声明需要暴露的服务接口 --> <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" /> <!-- 和本地bean一样实现服务 --> <bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" /> </beans>
1.4 加载Spring配置Provider.java
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Provider { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"http://10.20.160.198/wiki/display/dubbo/provider.xml"}); context.start(); System.in.read(); // 按任意键退出 } }
2. 服务消费者
2.1 通过Spring配置引用远程服务consumer.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 --> <dubbo:application name="consumer-of-helloworld-app" /> <!-- 使用multicast广播注册中心暴露发现服务地址 --> <dubbo:registry address="multicast://224.5.6.7:1234" /> <!-- 生成远程服务代理,可以和本地bean一样使用demoService --> <dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" /> </beans>
2.2 加载Spring配置,并调用远程服务Consumer.java
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.alibaba.dubbo.demo.DemoService; public class Consumer { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"http://10.20.160.198/wiki/display/dubbo/consumer.xml"}); context.start(); DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理 String hello = demoService.sayHello("world"); // 执行远程方法 System.out.println( hello ); // 显示调用结果 } }
3. 总结
3.1 该接口需单独打包,在服务提供方和消费方共享
3.2 对服务消费方隐藏实现
3.3 也可以使用IoC注入
参考文章:https://www.cnblogs.com/leeSmall/p/9824591.html
7.2 dubbo底层协议
底层的调用协议http、rmi、netty(dubbo)
7.3 dubbo服务注册与发现流程
调用关系说明:
1. 服务容器负责启动,加载,运行服务提供者。
2. 服务提供者在启动时,向注册中心注册自己提供的服务。
3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败, 再选另一台调用。
6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
总结:
生产者启动时把接口注册到注册中心,消费者启动时从注册中心获取生产者的接口列表放到本地,当有请求过来时,从消费者的本地获取生产者的接口列表选择一个生产者使用底层的调用协议(http、rmi、netty(dubbo))去调用,dubbo同时还能对服务进行监控
四、SpringBoot
1、SpringBoot与SpringMVC差异化在哪
1.首先这两者专注的领域不同,解决的问题也不一样
2.Spring MVC是基于 Servlet 的一个 MVC 框架,通过Dispatcher Servlet, ModelAndView解决 WEB 开发的问题.但是它的配置繁琐,大量 .xml、.properties文件。并且用maven管理项目的时候很容易出现jar包冲突。
3.而Spring Boot 是基于Spring的一套快速开发整合包,它不仅仅包含了spring mvc ,还包括 spring JPA、spring security等实现自动配置,降低项目搭建的复杂度.而且自带tomcat.pom.xml 中可以使用 starter的方式配置,简化配置还能解决jar包冲 突问题。
spring-boot-starter-web spring-boot-starter-data-jpa spring-boot-starter-redis
4.但他们的基础都是Spring 的 IOC 和 AOP
5.spring mvc 打包后是war包,spring boot 是jar包
2、为什么说Spring是一个容器
Spring通过IOC创建和管理bean实例,所以Spring也称为IOC容器
3、常用注解@Required @Autowired @Qualifier @Controller @RequestMapping
@Required
注解作用于Bean setter
方法上,用于检查一个Bean的属性的值在配置期间是否被赋予或设置(populated),否则,容器会抛出一个BeanInitializationException异常。
示例:
package com.jsoft.testspring.testannotationrequired; import org.springframework.beans.factory.annotation.Required; public class Student { private Integer age; private String name; @Required public void setAge(Integer age){ this.age = age; } public Integer getAge(){ return this.age; } public void setName(String name){ this.name = name; } public String getName(){ return this.name; } }
beans.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean id="student" class="com.jsoft.testspring.testannotationrequired.Student"> <property name="name" value="Jim"/> </bean> </beans>
App.java:
package com.jsoft.testspring.testannotationrequired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Hello world! * */ public class App { public static void main( String[] args ) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student)applicationContext.getBean("student"); System.out.println(student.getAge()); System.out.println(student.getName()); } }
而此时的运行结果是出现了错误的,因为age的setter方法没有在bean中注入,而age的setter方法标记了@Required,也就是必须要输入,抛出的异常为:BeanInitializationException。
那么我们将beans.xml补全之后:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean id="student" class="com.jsoft.testspring.testannotationrequired.Student"> <property name="name" value="Jim"/> <property name="age" value="27"/> </bean> </beans>
此时的运行结果一切正常:
@Autowired自动装配
@Autowired顾名思义,就是自动装配,其作用是为了消除代码Java代码里面的getter/setter与bean属性中的property。当然,getter看个人需求,如果私有属性需要对外提供的话,应当予以保留。
@Autowired默认按类型匹配的方式,在容器查找匹配的Bean,当有且仅有一个匹配的Bean时,Spring将其注入@Autowired标注的变量中。
@Qualifier(指定注入Bean的名称)
如果容器中有一个以上匹配的Bean,则可以通过@Qualifier注解限定Bean的名称
使用 @Controller 定义一个 Controller 控制器
例1:
@Controller public class MyController { @RequestMapping ( "/showView" ) public ModelAndView showView() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName( "viewName" ); modelAndView.addObject( " 需要放到 model 中的属性名称 " , " 对应的属性值,它是一个对象 " ); return modelAndView; } }
例1所示@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器,这个接下来就会讲到。
单单使用@Controller 标记在一个类上还不能真正意义上的说它就是SpringMVC 的一个控制器类,因为这个时候Spring 还不认识它。那么要如何做Spring 才能认识它呢?这个时候就需要我们把这个控制器类交给Spring 来管理。
这个时候有两种方式可以把MyController 交给Spring 管理,好让它能够识别我们标记的@Controller 。
第一种方式是在SpringMVC 的配置文件中定义MyController 的bean 对象。
<bean class="com.host.app.web.controller.MyController"/>
第二种方式是在SpringMVC 的配置文件中告诉Spring 该到哪里去找标记为@Controller 的Controller 控制器。
< context:component-scan base-package = "com.host.app.web.controller" > < context:exclude-filter type = "annotation" expression = "org.springframework.stereotype.Service" /> </ context:component-scan >
注:
上面 context:exclude-filter 标注的是不扫描 @Service 标注的类
使用 @RequestMapping 来映射 Request 请求与处理器
例1可以使用@RequestMapping 来映射URL 到控制器类,或者是到Controller 控制器的处理方法上。当@RequestMapping 标记在Controller 类上的时候,里面使用@RequestMapping 标记的方法的请求地址都是相对于类上的@RequestMapping 而言的;当Controller 类上没有标记@RequestMapping 注解时,方法上的@RequestMapping 都是绝对路径。这种绝对路径和相对路径所组合成的最终路径都是相对于根路径“/ ”而言的。
在这个控制器中,因为MyController 没有被@RequestMapping 标记,所以当需要访问到里面使用了@RequestMapping 标记的showView 方法时,就是使用的绝对路径/showView.do 请求就可以了。
例2:
@Controller @RequestMapping ( "/test" ) public class MyController { @RequestMapping ( "/showView" ) public ModelAndView showView() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName( "viewName" ); modelAndView.addObject( " 需要放到 model 中的属性名称 " , " 对应的属性值,它是一个对象 " ); return modelAndView; } }
4、谈谈对AOP的理解
Aspect Oriented Programming 面向切面编程,在不改变类的代码的情况下,对类方法进行功能增强。
我们先来看一下下面的这张图
说明:
程序运行时会调用很多方法,调用的很多方法就叫做Join points(连接点,可以被选择来进行增强的方法点),在方法的前或者后选择一个地方来切入,切入的的地方就叫做Pointcut(切入点,选择增强的方法),然后把要增强的功能(Advice)加入到切入点所在的位置。Advice和Pointcut组成一个切面(Aspect)
AOP的几个概念:
5、怎样开启注解装配
在Spring配置文件中配置 <context:annotation-config/>元素。
6、描述模板JdbcTemplate RestTemplate
JdbcTemplate :
JdbcTemplate简介
Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。
JdbcTemplate位于中。其全限定命名为org.springframework.jdbc.core.JdbcTemplate。要使用JdbcTemlate还需一个这个包包含了一下事务和异常控制
JdbcTemplate主要提供以下五类方法:
-
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
-
update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
-
query方法及queryForXXX方法:用于执行查询相关语句;
-
call方法:用于执行存储过程、函数相关语句。
RestTemplate:
RestTemplate是Spring提供的用于访问Rest服务的客户端,
RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用java.net包下的实现创建HTTP 请求,
可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式。
ClientHttpRequestFactory接口主要提供了两种实现方式
1、一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接。
2、一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。
7、Spring支持的事务管理类型
一种编程式和三种声明式
一种编程式(基于底层 API txManager.getTransaction方式或基于TransactionTemplate)
三种声明式:AOP(TransactionProxyFactoryBean),基于AspectJ的声明式事务<tx:advice>,基于注解方式的声明式事务(@Transactional)
编程式事务侵入性比较强,但处理粒度更细。
8、Spring框架的事务管理有哪些优点
它为不同的事务API(如JTA, JDBC, Hibernate, JPA, 和JDO)提供了统一的编程模型。
它为编程式事务管理提供了一个简单的API而非一系列复杂的事务API(如JTA).
它支持声明式事务管理。
它可以和Spring 的多种数据访问技术很好的融合。
9、Spring Boot Starter内容及工作原理
内容:
SpringBoot 的最终奉行的宗旨:废除掉所有复杂的开发,废除掉所有的配置文件,让开发变得更简单纯粹,核心:“零配置”。
SpringBoot整合了所有的框架,就像maven整合了所有的jar一样,使用方便
SpringBoot 之所以慢慢可以火遍全世界,是因为在 SpringBoot 中使用的大量注解还是之前 Spring 所提供的注解,那么这一点
让所有的开发者几乎可以零适应进行完整过渡。其次是开发快速、简单、方便
工作原理:
1. 入口
有@springbootApplication注解的类就是入口,@springbootApplication注解是一堆注解的集合。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), 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; }
4. META-INF/spring.factories
这个属性配置文件就指明了springboot工程启动的时候需要做哪些自动配置:
# Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\ org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer # Application Listeners org.springframework.context.ApplicationListener=\ org.springframework.boot.autoconfigure.BackgroundPreinitializer # Auto Configuration Import Listeners org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\ org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener # Auto Configuration Import Filters org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\ org.springframework.boot.autoconfigure.condition.OnClassCondition # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\ org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\ org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\ org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\ org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\ org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\ org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\ org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\ org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\ org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\ org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\ org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\ org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\ org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\ org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\ org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\ org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\ org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\ org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\ org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\ org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\ org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\ org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\ org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\ org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\ org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\ org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\ org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\ org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\ org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\ org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\ org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\ org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\ org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\ org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\ org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\ org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\ org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\ org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration # Failure analyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer # Template availability providers org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider
上面都是类的全限定名,那么这些类放在哪里呢?就在spring-boot-autoconfiguration.jar下面
从上面可以看出springboot工程一起动,其实自动帮助我们配置很多东西比如(solr、redis、mq、web等等),只不过这些以前是程序员手动通过xml配置的,现在呢,是springboot通过java配置的方式自动帮助我们配置的。
序列化