【面试必背】Spring篇

本文深入剖析Spring框架的核心特性,包括控制反转(IOC)和面向切面编程(AOP),详细阐述了bean的生命周期以及如何处理循环依赖。此外,还介绍了Spring的事务管理,包括编程式和声明式事务,并探讨了事务隔离级别和传播行为。文章还涵盖了Spring的其他关键概念,如动态代理(JDK和CGLIB)、设计模式和Spring Boot的自动装配。
摘要由CSDN通过智能技术生成

Spring

Spring

轻量级java开发框架,解决业务逻辑层和其他层的耦合问题,简化开发

核心特性

IOC

		控制反转,将原本在程序中手动创建对象的控制权交给Spring框架来管理,不需要我们手动new对象
		将对象相互依赖关系交给IOC容器来管理,并由IOC容器完成对象的注入,简化开发,将应用从复杂的依赖关系中解放出来
		IOC像工厂一样,当我们需要创建一个对象是,只需要配置好文件或注解,不需要考虑对象是怎么创建的
		反射
			运行时,对于一个类,可以拿到类的所有属性和方法,对于一个对象,可以调用方法的所有属性和方法,并可以更改对象属性

AOP

		面向切面编程,将与业务无关,与业务模块共同调用的逻辑封装起来,减少重复代码,降低耦合度,增强可拓展,可维护。

使用jdk和cglib动态代理方式,对事务、日志、鉴权等功能
基于动态代理,代理的对象实现了某个接口,spring aop会使用jdk动态代理去创建代理对象
对于没有实现接口的对象,可以使用cglib动态代理生成一个被代理对象的子类作为代理
Spring AOP集成了AspectJ,编译时增强,基于字节码操作

jdk和cglib区别
			依赖原class生成新的class
			通过jar包生成代理类

生命周期

	bean实例化
	填充属性,将值和bean引用注入到bean对应属性中
	将bean的id传递给setBeanName方法
	将beanFactory容器实例传入,调用工厂的setBeanFactory方法
	调用ApplicationContextAware的setApplicationContext方法
	调用BeanPostProcessor预初始化方法
	调用初始化Bean的afterPropertiesSet方法
	调用自定义初始化方法
	调用BeanPostProcessor初始化方法
	使用bean
	容器关闭
	调用DisposableBean的destory方法
	调用自定义销毁方法

设计模式

	单例
		bean默认为单例
	工厂
		BeanFactory,创建实例
	代理
		AOP用jdk和cglib动态代理
	模板
		解决重复代码,RestTemplate
	观察者
		一对多依赖关系,一个对象状态发生改变时,所有依赖他的对象都会得到通知更新,ApplicationListener

循环依赖

	spring ioc容器读取bean配置创建bean实例之前,必须对它进行实例化,只有在容器实例化后才可以从ioc容器里获取bean实例并使用
	A引用B,B引用A,spring启动后,读取配置文件,会按顺序先实例化A,创建时发现A引用B,就去实例化B,又发现B引用了A,发生循环依赖,注入出现死循环
	spring实例化对象分两步,1:创建一个原始对象,只是没有设置属性,2:实例化B时发现依赖A,B会将A设置进去先实例化,B完成了实例化,A可以获取B的引用,也完成了实例化
	通过getBean()去获取一个对象实例时,spring从一级缓存找,一级没有再去二级,一二级都有找到,表示bean还未实例化,spring容器会实例化这个bean,初始化实例的bean叫早期bean,会将目标bean放入二级缓存,同时加入一个标记,表示是否存在循环依赖,如果不存在,就放入二级缓存,否则会标记这个bean存在循环依赖,再等待下一次轮询时去赋值,也就是解析@Autowired注解,@Autowired赋值完成后会将目标bean存入一级缓存
	一级缓存存放所有成熟的bean
	二级存放所有早期的bean
	先取一级再取二级
	用来存储代理bean,调用getBean方法时发现目标bean需要通过代理工厂来创建,会将创建好的实例放到三级缓存,将赋值好的bean同步到一级缓存
三级缓存
		1. 单例池
			存放完全初始化好的bean集合,从集合中取出来的bean可以立马返回
		2.提前曝光对象
			存放创建好但没初始化属性的bean集合
		3.提前曝光对象工厂
			存放单实例bean工厂集合
	多实例bean通过Setter注入
	构造器注入的bean
	单例的

事务管理

编程式事务
声明式事务
		配置文件中配置,基于XML/注解的声明式事务

事务隔离级别

	ISOLATION_DEFAULT
		默认隔离级别,可重复读
	ISOLATION_READ_UNCOMMITTED
		最低,允许读取尚未提交的数据
	ISOLATION_READ_COMMITTED
		读已提交
	ISOLATION_REPEATABLE_READ
		同一字段多次读取结果一致
	ISOLATION_SERIALIZABLE

事务传播行为

	一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行
	PROPAGATION_REQUIRED
		存在一个事务,支持当前事务
	存在则加入,没有则创建新事务
	存在则加入,没有则非事务
	存在则加入,没有抛异常

@Transactional

失效
		标注方法修饰符为非public
		类内部调用事务方法
		事务方法内部捕捉异常,没有抛出异常
		作用于线程池
			线程池不属于spring方法,不生效
原因
		使用AOP,生成代理类,执行相关方法时判断是否有@Translation注解,有则开启事务,目标对象内部自我调用无法实施切面中的增强

注解

请求参数
		@RquestHeader("token") String token

获取token
@RestController(“/…”)
@RequestMapping(“/{id}”) PathVariable Long id
@RequestMapping(“/id”) RequestParam
@RequestMapping(“/id”) RequestBody User user

校验参数
		@NotBlank
		@Valid
mapper
		insert返回id
			keyProperty
feign
	@FeignClient(value="B" fallback=BException.class)
	@RestController
		复合注解,包括@Controller和@ResponseBody
	@Autowired
		先byType再byName
		找到所有类型符合的bean,没有符合,看required属性是否为true,是抛异常,否则null
		如果只有一个,则将隱‘注入
		多个bean,带有primary注解的bean
	@Resource
		先byName再byType
		指定name,只会按照name来查找,找不到抛异常,找到将bean注入

Spring MVC

浏览器发起请求,到DispatcherServlet
DispatcherServlet根据请求调用HandlerMapping,解析请求对应的Handler
HandlerAdater会根据Handler调用真正的处理器来处理请求和执行相对应的业务逻辑
逻辑处理完后,会返回一个ModelAndView对象
DispatchServlet将返回的Model传给View
View返回给浏览器

SpringBoot

自动装配

	配置文件定义属性,自动装配到所属依赖的类中,以动态代理的方式注入到spring容器中
	SpringBoot无需配置文件,一个main方法就能将项目启动
	SpringBoot通过main方法启动SpringApplication类的静态方法run()来启动项目,run方法是从一个使用了默认配置的指定资源启动一个SpringApplication并返回ApplicationContext对象。

默认配置来源于@SpringBootApplication注解,这个注解是个复合注解,里面还包含了其他注解。
@SpringBootConfiguration:底层是一个@Configuration注解,被Configuration注解修饰的类是一个IOC容器,支持JavaConfig方式来进行配置
@ComponentScan:这个就是扫描注解的意思,默认扫描当前类所在的包及其子包下包含的注解,将@Controller/@Service/@Component/@Repository等注解加载到IOC容器中
@EnableAutoConfiguration:这个注解表明启动自动装配,里面包含几个比较重要的注解@AutoConfigurationPackage和@Import。是将主配置类所在的包及其子包里面的组件扫描到IOC容器中
@AutoConfigurationPackage扫描@Enitity、@MapperScan等第三方依赖的注解
@Import(AutoConfigurationImportSelector.class)是自动装配的核心注解,AutoConfigurationImportSelector.class中有个selectImports方法,会调用loadFactoryNames方法,会扫描pom.xml文件中其他starter,将第三方jar包引入到spring.factories,方法有个断言,用来找META-INF/spring.factories文件,文件在spring-boot-autoconfigure.jar包中,存储key value,key为EnableAutoConfiguration全类名,value为_AutoConfiguration类名自动配置类的列表,都逗号分隔。
@EnableAutoConfiguration注解通过@SpringBootApplication注解被间接的标记在了SpringBoot的启动类上,SpringApplicaton.run方法的内部就会执行selectImports方法,进而找到所有JavaConfig配置类全限定名对应的class,将所有自动配置类加载到IOC容器中

SpringCloud

分布式微服务的技术解决方案,提供了快速构建分布式系统常用的组件,如配置管理、服务注册与发现、服务调用的负载均衡、资源隔离、熔断降级等
可以快速落地微服务的解决方案,快速解决分布式遇到的一些问题,不需要去考虑第三方技术集成带来的额外成本,只需要通过一些简单的配置组件,可以完成在微服务架构下落地的一些技术问题,让我们更加关注代码业务层面
Netfix,Ribbon负载均衡、hystrix熔断、Eureka注册中心、Zuul服务网关、Feign服务调用。
Alibaba,Nacos服务注册与配置中心、Sentinel服务监控降级、Seata分布式事务、RocketMQ分布式消息系统、Dubbo RPC通讯
SpringBoot专注快速开发单个个体微服务,SpringCloud关注全局微服务协调治理框架,管理各个微服务

Eureka

	注册中心,eureka client将服务注册到Eureka Server,eureka client也可以从Eureka Server拉取注册表,从而知道其他服务在哪

eureka client定时向eureka server发送心跳包
AP
eureka 挂掉
eureka在server端一定时间内(默认90s)没有收到心跳,直接从服务注册列表剔除该服务,如果短时间内丢失大量的服务实例心跳,eureka server会开启自我保护机制,不会剔除该服务。
宁可保留所有健康和不健康的服务,也不盲目注销任何可能健康的服务
provider和consumer分别注册到eureka,consumer要调用provider,在eureka中查询provider具体地址和端口,获取到后直接调用provider,一旦consumer获取到provider地址就不需要eureka了,所以eureka挂掉,provider没有更换ip和端口,服务仍能相互调用

Nacos

	注册中心和配置中心
	nacos使用netty长链接,eureka短链接,定时发送
	支持雪崩保护,10机器,6台挂了,为了保证所有请求不全部打到健康的服务器上导致服务器承受不住崩掉,会随机将部分请求分发到不健康的节点
	AP/CP

Ribbon

	负载均衡,一个服务多台机器选择一台

Feign

	动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求
	REST模板
	某个接口定义了@FeignClient注解,Feign会针对这个接口创建一个动态代理

调用那个接口,本质就是调用Feign创建的动态代理,会根据你在接口上的@RequestMapping等注解,来动态构造出你要请求服务的地址,根据这个地址发起请求、解析响应

Hystrix

	通过Hystrix线程池,不同服务走不同线程池,实现不同服务调用隔离,避免服务雪崩
	失败调用到一定阈值,默认5s内调用20次,失败就熔断
	熔断
		应对雪崩,先降级再熔断
	降级
		服务器不再调用,返回兜底

Zuul

	网关,所有网络请求的入口,通过网关转发到具体服务

统一管理请求,权限控制、负载均衡、路由转发、监控、安全控制黑名单和白名单

consul

每个服务都有一个consul agent,agent不断发送请求检查服务是否健康,服务故障时,会发送消息通知consul server leader,避免短时间内向注册中心server发送大量心跳请求

Gateway

异步
限流、负载均衡
大型项目适合

gRPC

使用TCP通信,C和S建立socket连接,http2.0协议,序列化,二进制转对象
跨语言
定义请求request,包含一个message字段表示请求内容,响应response,服务service提供一个方法,request作为方法参数并返回response
  1. client调用服务client stub
  2. client stub序列化到server stub
  3. server stub解码,调用服务server
  4. server收到请求,返回结果给server stub
  5. server stub将结果序列化到client stub
  6. client stub反序列化给client
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值