spring-springboot -springcloud
目录
spring:
动态代理:
spring的生命周期(bean的生命周期):
SpringMvc的生命周期:
SpringBoot:
自动装配:
自动装配流程:
Spring中常用的注解:
Spring Boot中常用的注解:
SpringCloud:
1. 注册中心:
2. gateway(网关):
3. Ribbon(负载均衡): 它是一个基于http协议请求的客户端负载均衡
4. Hystrix(断路器,熔断器):
5. Feign(远程调用):
6. Sentinel:
7. 雪崩及处理方式:
分布式事务:
spring:
它是一个轻量级的容器架构,提供了ioc控制反转, di依赖注入, aop面向切面编程,支持web开发,事务管理以及强大的安全性,能够是开发人员更加专注于业务逻辑的实现,不必过多关注底层的技术细节
控制反转: spring通过控制反转实现了对象的管理和创建,传统的开发模式中,对象的创建和依赖关系的管理是有开发人员手动处理的,而在spring中,对象的创建和依赖关系的注入有spring容器负责,只需要声明依赖关系无需关系对象的创建和销毁
依赖注入: 将对象的依赖关系交给spring管理,spring会根据配置文件或注解,自动将依赖的对象注入到需要的地方,实现松耦合的组件之间的协作
面向切面编程: 它是一种编程范式,通过将横切的关注点与核心业务逻辑分离,提高系统的可维护性和可扩展性,它的本质是动态代理
1. 切面: 切面是横切关注点的模块化单元,包含了一组通知和切点.通知是定义在何时何地执行特定的操作,切点定义在哪些地方应用这些操作,切面可以被织入到目标对象中,从而实现目标对象的增强
2. 通知: 切面中定义的具体操作,定义了切点础执行的代码.通知可以在目标方法执行前,执行后,或抛异常时执行,也可以在目标方法执行过程中多次执行,常见的类型有:(前置通知, 后置通知, 返回通知和异常通知)
3. 切点: 在程序中定义的一个或多个连接点的集合,连接点是程序中可以插入切面的特定位置,例如方法调用,方法执行异常抛出等,切点通过表达式或注解方式定义,用于确定在哪些连接点上应用切面通知
4. 将切面应用到目标对象中的过程,织入可以在编译时,类加载时或运行时进行,AOP框架会根据切点的定义,将切面的通知插入到目标对象的连接点上,从而实现对目标对象的增强
动态代理:
JDK动态代理: 是java提供的一种基于接口实现的代理技术,通过java反射机制,在运行时动态的创建代理对象,它要求目标类实现接口,代理对象通过实现接口在代理目标类的方法
CGLIB动态代理: 是一种基于继承的代理技术,通过生成目标类的子类来作为代理对象,并重写目标类的方法实现增强逻辑,他它要求目标类实现接口,可以代理普通类,但是无法处理final修饰的类
区别: 从性能上来说,jdk动态代理使用java的反射机制,比cglib动态代理更轻量级,执行效率更高,而cglib动态代理是通过生成子类来实现代理,涉及到类的继承和方法的重写,效率较低
spring的生命周期(bean的生命周期):
1. 加载配置文件: 通过XML配置文件或者注解的方式进行配置. 配置文件中定义了bean的定义,依赖关系, 初始化方法以及销毁方法等,spring使用applicationContext或者BeanFactory加载配置文
加载配置文件的方式:
1. applicationContext 加载配置文件
2. BeanFactory 加载配置文件
3. ClassPathXmlApplicationContext 实现类加载XML配置文件
4. FileSystemXmlApplicationContext 实现类加载XML配置文件
5. AnnotationConfigApplicationContsxt 加载基于注解的配置类
2. 创建容器: 根据配置文件中的定义,创建一个应用程序上下文(ApplicationContext),也称为容器,容器负责管理bean的生命周期和依赖关系的注入
容器的创建由applicationContext或BeanFactory实现,创建容器时spring会解析配置文件并根据配置信息初始化容器
3. 实例化bean: 根据配置方式的不同,可以使用构造函数实例化bean或者通过工厂方法创建bean的实例, 根据配置文件中的bean定义,使用beanDefinition创建bean实例
4. 设置属性: 容器会将配置文件中定义的属性值注入到bean的实例中,可以通过setter方法或直接访问成员变量进行属性的设置
5. 调用初始化方法: 如果bean定义了初始化方法(可以根据配置文件的init-method或注解@PostConstruct指定), 容器会在属性设置完成后调用该方法进行一些初始化操作
6. bean使用: 初始化完成后,可以应用程序中使用了,其他的bean可以通过依赖注入的方式使用该bean
7. bean销毁: 应用程序关闭或容器被销毁时, 容器会调用bean的销毁方法(可以通过配置文件destroy-method或注解@PreDestroy指定)来进行一些清理工作
spring还提供了bean后置处理器机制,能够在bean的初始化前后进行一些自定义的处理操作,通过实现beanPostProcessor接口在bean生命周期的特定阶段插入自己的逻辑
SpringMvc的生命周期:
客户端发松http请求到springmvc应用程序,请求被DispatcherServlet接收并分发给相应的处理器进行处理,处理器映射器会根据请求的url或其他条件确定使用那个处理器,并将请求映射到一个或多个处理器,由处理器适配器将请求发生给相应的处理器进行处理,执行业务逻辑后并生成模型数据,返回给视图解析器,由视图解析器进行解析和渲染最后返回给客户端
场景题: aop事务怎么开启和提交
在spring中开启事务可以使用@Transactional, 作用在方法或类级别上表示需要进行事务管理,spring会自动创建一个事务并在方法执行前开启事务,事务的提交是由事务管理器自动处理的,方法执行完成后,如果没有发生异常,事务管理器会将事务提交到数据库中,使操作生效,否则事务管理器会回滚事务并取消之前的操作
SpringBoot:
它是一个用于简化和加快springBoot应用程序开发的开源框架,基于spring框架,并提供了自动配置,快速启动,无需繁琐的xml配置等特性,使开发者可以更专注业务逻辑的开发不必过多关注框架的配置
自动配置: 通过自动配置机制,根据应用程序的依赖和配置,自动配置spring框架的各种组件和功能
快速启动: 内嵌servlet容器,可以直接运行spring应用程序,不需要部署到外部容器
无需xml配置: 通过注解和约定,可以更简洁的配置spring应用程序,并减少配置文件的数量和复杂性
起步依赖: 它提供了一系列预配置依赖项,称为起步依赖,能够简化对常用功能的集成(例如数据库访问,web开发,安全性等),并自动处理依赖冲突和版本兼容性
健康检查和监控: 提供了健康检查和监控功能,可以通过http端点获取应用程序的运行状况和性能指标
集成测试支持: 提供了一套方便的测试工具,可以轻松编写集成测试和端到端测试,这些工具可以模拟和管理应用程序的环境,简化测试的编写和执行
自动装配:
实际上是为了从spring.factories文件中获取到对应的需要进行装配的类,并生成相应的bean对象后交给spring管理
@SpringBootApplication: 它是一个组合注解,标记这个类为主配置类,springboot运行里面的main方法来启动程序
@SpringBootConfiguration: 用于定义和组织bean的创建和配置的类,被他标记的类springboot会自动识别为配置类
@EnableAutoConfiguration: 开启自动自动配置的功能,自动扫描和匹配依赖
@ComponentScan: 指定spring要扫描的组件和包路径,将其纳入到spring的管理范围
@AutoConfigurationPackage: 将主配置类所在包以及子包里面的所有组件扫描并加载到spring容器中
@Import(AutoConfigurationImportSelector.class): 将需要自动装配的类以全类名的方式返回
自动装配流程:
1. 启动应用程序: 当springboot应用程序启动时,会创建一个spring应用上下文(ApplicationContext)
2. 加载字段配置类: springboot会自动扫描spring.factories文件,该文件中列出了所有自动配置的类全限定名,springboot会自动加载这些配置类并纳入到应用程序上下文中
3. 条件化装配: 每个自动配置类都会使用条件注解(@ConditionalOnClass, @ConditionalOnProperty等)来判断是否满足特定条件,满足配置类会生效,否则会被忽略
4. 解决依赖关系: 他会检查bean定义中的依赖,并尝试将这些依赖注入到合适的bean实例中
5. springboot会自动加载应用程序的配置文件(application.yml或application.properies),并将属性绑定到相应的bean中
6. 完成自动装配: 当所有的自动配置类被处理完后,bean的依赖关系都被满足时,自动装配完成
Spring中常用的注解:
@Component:用于将一个类标识为Spring容器中的组件,让Spring自动扫描并创建该类的实例。
@Autowired:用于自动注入依赖,通过类型匹配实现依赖注入。
@Configuration:用于标识一个类为配置类,其中定义的Bean将被Spring容器管理。
@Bean:用于在配置类中定义一个Bean,Spring容器会根据该注解创建Bean实例。
@ComponentScan:用于指定Spring要扫描的组件的基本包路径。
@RequestMapping:用于映射HTTP请求到控制器方法,指定URL路径和请求方法。
@Controller:用于标识一个类为控制器,处理用户请求并返回响应。
@Service:用于标识一个类为服务层组件,通常用于业务逻辑的处理。
@Repository:用于标识一个类为数据访问层组件,通常用于数据库操作。
@Scope:用于指定Bean的作用域,如singleton(单例)、prototype(原型)等。
@Qualifier:与@Autowired配合使用,通过指定Bean的名称或ID来解决依赖注入的歧义性。
Spring Boot中常用的注解:
@SpringBootApplication:用于标识一个类为Spring Boot应用程序的入口点,包含了@Configuration、@EnableAutoConfiguration和@ComponentScan注解。
@EnableAutoConfiguration:用于开启Spring Boot的自动配置功能。
@Transactional:用于标识一个方法或类需要事务支持,实现数据库事务的管理。
@Value:用于注入配置文件中的属性值到一个Java变量。
@RestController:用于标识一个类为RESTful风格的控制器,类中的方法默认返回JSON格式的数据。
@GetMapping、@PostMapping等:用于映射HTTP请求到控制器方法,指定URL路径和请求方法。
@ConfigurationProperties:用于绑定配置文件中的属性值到一个Java对象,简化配置的读取和管理。
@EnableScheduling:用于开启Spring的定时任务调度功能。
@EnableCaching:用于开启Spring的缓存功能。
@ConditionalOnProperty:根据配置文件中的属性值来决定是否启用某个配置。
SpringCloud:
springCloud是spring家族中一款基于http协议的组件,是一系列框架的有序集合,利用了springboot开发便利性简化了分布式系统基础设施的开发,对于服务的注册发现,限流,熔断,降级,负载均衡等都可以使用springboot一键启动和部署
1. 注册中心:
_1. eureka: 注册中心先启动,服务提供者会在注册中心进行注册,并且每30秒向注册中心发送一次心跳,消费者服务启动会去注册中心拉取服务提供者的服务名称
缺点: 当服务提供者发生故障时,30秒后注册中心没有收到心跳,那么注册中心会给服务提供者三次机会,也就是90秒的时间,如果注册中心一直没有收到心跳则会将这个服务踢除,被踢除后服务注册中心不会主动将这个服务不存在的消息推送给消费者服务,消费者服务会在90秒内再次访问服务提供者的话就会报错,但是过了90秒后就不会了
_2. nacos: 注册中心启动后,启动服务提供者,服务提供者会去注册中心的服务列表注册服务名称,并每隔5秒发生一次心跳,注册中心还会主动的去获取这个服务是否存在,消费者服务启动后会去服务列表中拉取服务名称,就算服务提供者发生故障,注册中心会主动的获取这个服务是否存在并将信息 推送给消费者服务,这个就不会存在Eureka中存在的问题了
nacos不仅能作为注册中心,还能够作为配置中心,可以同一管理微服务的配置文件,需要热更新的配置放在配置中心里面,微服务会主动的去拉取最新的配置信息
2. gateway(网关):
用于处理客户端请求的路由,过滤和转发等功能,作为系统的统一访问入口,将外部请求转发到不同的微服务实例,并提供请求的认证,授权,限流和监控等功能
_1.路由转发: 根据请求的url路径和参数将请求转发到相应的微服务实例,可以根据路由的规则动态的请求转发和负载均衡,实现请求的动态路由和负载均衡
_2. 认证和授权: 可以对请求进行认证和授权,确保只有经过认证和授权的请求才能访问相应的微服务
_3.. 限流和熔断: 对请求进行限流和熔断,防止微服务被过多的请求压垮,根据请求的qps(每秒请求数)进行限制,并在微服务出现故障或超时时进行熔断,避免级联故障
_4. 监控和统计: 对请求进行监控和统计,收集请求的指标数据,如请求的响应时间,成功率等,通过监控的数据分析系统的性能和蒋康状况,及时发现和解决问题
3. Ribbon(负载均衡): 它是一个基于http协议请求的客户端负载均衡
当请求进入网关后会经过RibbonLoadBalancerClient客户端,通过客户端去获取服务名称,在去注册中心的服务列表拿到服务的地址,最后客户端根据服务地址以负载均衡的策略调用微服务(默认以轮询方式)
他默认使用懒加载,也就是第一次访问的时候才会去访问客户端,这样就会导致第一次请求的时间很长,我们可以在配置文件中配置为饥饿加载降低第一次的访问时长
负载均衡策略:
_1. 轮询: 按照顺序依次将请求分发给每个微服务,循环往复,实现请求的均匀分发
_2. 随机: 随机选择一个服务处理每个请求,每个请求都有随机的概率被分发到不同的微服务中,实现了请求的随机分发
_3. 加权轮询: 给每个微服务分配一个权重值,权重值越高的微服务被选中的概率越大,根据服务的性能,负载情况等因素调整这个权重值,实现请求的按比例分发
_4. 加权随机: 给每个服务分配一个权重值,将请求随机分发给服务处理,权重值越高的被选中的概率越大
_5. 最少连接: 选择当前连接数最少的服务来处理请求,通过统计到每个服务的当前连接数,选择最少的服务,实现请求的负载均衡
_6. 最短响应时间: 根据每个服务响应时间选择最快的服务处理请求
4. Hystrix(断路器,熔断器):
断路器是统计发生的异常比例,如果达到了qps阈值则会开启熔断器,熔断器会默认开启5秒,5秒内会拦截一切请求,5每秒后会进入半熔断状态并尝试放行一个请求,如果能够成功方伟微服务,那么熔断器就会处于关闭状态,整个过程是循环的
5. Feign(远程调用):
他提供了http请求模版,通过编写简单的接口和插入注解,就可以定义好http请求参数,格式,地址等信息
在启动类上使用注解@EnableFeignClients开启远程调用
_1. 创建feign客户端接口: 定义一个java接口,使用feign的注解描述远程服务的调用方式
@FeignClient(name = "service-provider") // 指定服务提供者的名称
public interface MyFeignClient {
@GetMapping("/api/resource/{id}")
Resource getResource(@PathVariable("id") Long id);
}
_2. 在需要远程调用服务的地方,通过依赖注入的方式使用feign客户端接口
@Autowired
private MyFeignClient feignClient;
public void doRemoteCall() {
Resource resource = feignClient.getResource(123L);
// 处理远程调用返回的结果
}
6. Sentinel:
是一个开源分布式系统的流量控制和熔断框架,解决流量控制,熔断降级,系统负责保护等问题,提供了实时监控,统计和告警功能
7. 雪崩及处理方式:
由于某个服务的故障或异常导致该服务所依赖的其他服务也出现故障或异常,最终导致整个系统的崩溃或无法正常工作的现象,这是请求的限流可以进行一个预防措施,熔断降级,超时处理,仓壁模式则可以对雪崩进行一个补救措施
仓壁模式: 也叫线程池隔离,给每个微服务设置一定数量的线程,避免Tomcat资源被耗尽,当某个服务发生故障后不会对其他服务参数影响
超时处理: 当大量请求进入sentinel后是以一个平稳的趋势,没有进入的我们设置一个等待时间,超过时间的返回一个超时提示避免陷入永久等待
分布式事务:
在分布式系统中涉及到的服务或数据库操作的一系列操作.要么全部执行成功,要么全部回滚,保证数据的一致性和可靠性,由于分布式系统的特点,如网络延迟,节点故障等,传统的单机事务无法直接应用到分布式环境中,因此需要采用特定的处理方式来处理分布式事务
_1. 两阶段提交: 2pc是一中同步的分布式事务处理方式,它包括协调组和参与者两个角色,在第一阶段,协调者询问所有参与是否可以提交事务,参与者根据自身状态回答,在第二阶段,协调者根据参与者的反馈决定是否提交事务,2pc的缺点是协调者单点故障,阻塞和数据不一致的风险
_2. 三阶段提交: 3pc是2pc的改进,引入了超时机制.