Spring原理

Bean的创建的生命周期
UserService.class  --->调用无参构造方法(推断使用哪个构造方法) --> 生成普通对象---> 依赖注入(属性赋值,找到Autowried) 
---->初始化前(@PostContruct) ---->初始化(afterPropertiesSet)--->初始化后(AOP)---->如果使用Aop,则成为代理对象---->Bean

如果想初始化一个Bean  ,比如是User的Bean  ,想初始化时 ,给User赋值 ,(从mysql中查询数据赋值) ,想要在初始化完成时有值,
那么在  初始化前,调用方法赋值即可,方法上添加 @PostContruct
也可以在Uservice类上实现InitializingBean  ,重写afterPropertiesSet ,赋值  .当然这一步是在初始化时实现的
如果Uservice中有有参构造,  public void UserService(OrderService orderService){}  那么Spring创建UserService时 ,会去找OrderService,
先根据参数类型寻找 ,如果只有1个 ,再根据参数名字去找  orderService . Bean对象方法Map里 (beanName,Bean)

切面的实现逻辑
1. 找出所有切面Bean 
2. 遍历切面Bean
3.遍历方法 ,看看有没有@Before ,@After 之类的属性
4. 方法中匹配是否有UserService ,判断是否需要切  .把UserService匹配的所有方法 放到缓存map
代理对象获取数据的流程  UserServiceProxy-->代理对象 -->代理对象.target=普通对象 (Bean生命周期第三步,普通对象是有值的),此时就能获取到Bean的数据


srping事务的代理逻辑 

1. 先判断是否有@Transation注解 ,
2. 如果有 ,创建一个数据库连接conn (由事务管理器创建PlatformTransactionManager)
3. conn.autocommit =false默认spring是true , 这里会变成false
4. 执行sql1  sql2

spring创建Bean的流程   IOC
Bean就是一个对象的实例化体现 .

Bean的加载流程 : 
通过读取配置/xml/javaconfig等等 ,读取到的信息放到BeanDefinition中 ,然后通过BeanFactory工厂 ,交给Spring管理
Spring集成任何框架 ,都要添加@Enablexxxx注解  ,这个注解底层又是@Import ,导入类 ,注册Bean定义

SpringBoot的自动配置原理 : 通过Import导入 DeffredImportSelector  . 为什么要导入DeffredImportSelector   ,因为考虑加载顺序的原因.
这里面定义的Bean是最后加载的 ,放在最后加载才能定制我们自己创建的Bean . 然后会扫描所有jar包中的spring.factory文件,封装成数组返回,交给Spring进行管理


srping容器创建 =new ApplicationContext() ,此时去读取配置信息,xml/config/scan配置等等,放到BeanDeinitionMap<beanName,BeanDefinition>中
BeanDefinition中被set一些Bean定义所需的信息也是此时完成 ,例如setBeanClass()等等

getBean   用来获取Bean对象   ,如果获取不到 ,那就去创建 --->拿到BeanDefinition(这里有Bean所需定义信息),通过BeanDefinition去创建Bean.
判断bean 是否是单例,是否是懒加载 ,之后使用BeanFactory工厂创建Bean  .
ApplicationContext是上层,封装了一整套流程,没有自己的实现,Factory只是创建bean的一个组件.
factory也会调用getBean方法 ,先去调用getSingleton ,去SingletonObjects<beanName,Object> (单例池)去寻找有没有已经创建好的bean ,如果没有,再去创建
创建 : 1. 实例化       使用反射,从之前的BeanDefinition中,拿到BeanClass,再getConstractor().newinstance()
         2. 依赖注入    解析@Autowried ,@Value等等,如果遇见多层注入(比如创建UserService,但是UserService里又注入了OrderService) ,再一次调用getBean .找到全部的需要的信息
    如果遇见循环依赖的情况 ,A-->B ,B-->A . 使用三级缓存解决 .
         3. 初始化       方法回调,人为设置Bean的一些属性 
     3.1 初始化前调用BeanPostProcessors.beforeXX 前置处理器                
     3.2 初始化后调用BeanPostProcessors.afterXX    后置处理器   总共会调用9次 ,创建过程调用8次,销毁时调用1次
     
ApplicationContext和BeanFactory的区别 :
 共同点 : 都可以作为容器 ,因为都提供getBean
 关系    :  BeanFactory规范ApplicationContext的行为 ,ApplicationContext使用BeanFactory生产Bean
 区别    : ApplicationContext自动化,生产Bean整套工序封装好了,BeanFactory只能生产Bean

springCloud Alibaba流程
微服务对比单体架构的好处 :
1 .高可用性,故障隔离 ,单体服务挂了就不能用了 . 微服务保证了高可用性
2 .代码解耦 
3 .团队拆分,便于管理
4.可伸缩可扩展性


Ribbon  是springcloudAlibaba默认提供的  ,在orderService服务的yml文件配置到 库存系统的服务地址 ,  stockService和orderService都注册到Nacos (服务注册中心),
Nacos实际上是一个Web服务 ,
order系统负责拉取配置,在orderService中的接口直接使用Restemplate ,http调用stockService,调用链接直接使用 http:stockService/xxx , 在RestTemplate上添加@Ribbon注解,Ribbon会自动路由到stock服务中
@Ribbon默认是轮询调用 ,@Ribbon底层会通过http的拦截器 ,把我们刚刚的调用链接的域名 ,直接解析成ip地址调用(通过拉取到的配置信息 也就是注册表)
服务注册通过定时心跳注册,5s一次  ,服务发现orderService也是定时拉取的,有个定时心跳检查任务


openFeign  .为了解决orderService调用服务通过 RestTemplate http调用很麻烦

FeignClient 注解的作用 : 在StockSercice接口上添加注解@FeignClient(value=stockService) ,比如有个方法叫减库存方法 deductStock()
底层通过动态代理 ,通过openFeign组件包,生成一个代理 ,这个代理会把上面配置的url地址 ,拼接好 ,借助Ribbon进行服务发现和调用

Sentinal服务原理 
用作服务降级使用  ,也可以配置限流,服务熔断
降级原理 :
使用方法 @FeignClient(fallback=CreditServiceFallback.class(积分服务))
当订单流程走到积分服务时,发现积分服务挂了 ,可以使服务不报错,继续调用其他流程
远程调用的 方法 ,实际上是走到了 Sentinal的 try catch里面  ,外层业务流程在 try里面 , 抛异常了则走到catch里面

限流原理 : 底层维护了一个滑动数组时间窗 ,假设第一秒调用10次 ,报错8次 ,记录到数组的第一个元素 ,第2秒调用以此类推,放到第二个元素中,第10秒,调用10次,报错9次
如果满足报错比例等 ,则直接打回请求,不会真正的调用服务

服务熔断 :  根据慢调用比例,异常比例 ,异常数等等, A->B>C  ,如果B服务处于假死状态  ,则A-调用B的降级方法 B->C 直接调用C ,
如果调用B接口报错比例到80% ,则不调用B服务了 ,直接掉用B服务的降级方法(比如记录日志)
熔断时长可配 ,假设10s  ,10s之内的总调用次数和报错次数的比例如果达到80%  ,那么每次熔断10s


Seata 分布式事务:
代码中添加 @GlobalTransactional  
底层方案 : AT模式 ,基于数据库的ACID ,通过Java的JDBC访问数据库
下订单 ,减库存 
首先订单下单服务成功 ,减库存服务失败 ,则协调服务会通知订单服务 ,进行回滚. 类似通过undo.log文件进行回滚 ,MVCC和read-view 
,实际上再Seata在后台也会记录一条对应的SQl语句 add对应delete .在同一个事务中
两阶段提交 :1阶段 业务数据和回滚日志记录在同一个本地事务中提交,释放连接资源
       2阶段 提交异步话 ,回滚通过日志进行反向补偿
Seata会有一些性能问题 .


springcloud 和Dubbo的区别 :
dubbo是一个RPC框架 ,核心是解决服务间调用的问题 ,spring是大而全的框架 ,dubbo更侧重服务调用 .可以结合起来使用

为什么dubbo不用JDK的spi  ,而是要自己实现
1 .java spi 的缺点 
 1.需要遍历所有实现并实例化 ,假设一个实现类初始化过程消耗资源又耗时 ,而自己的代码又用不到 ,产生资源浪费
 2. 没有使用缓存每次load都需要重新加载

2 dubbo spi 
 1. 给每个实现类配了个名字,通过名字取文件里面找到对应的实现类全限定名然后加载实例化,按需加载
 2.增加了缓存存储示例,提高读取性能
 3,提供了对IOC和AOP等高级功能的支持,以实现更多类型的扩展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值