赞
踩
目录
4.动态代理的实现方式(必考)是否使用过CGLiB,和JDK的区别是什么?
5.何时使用JDK还是CGLiB?如何强制使用CGLIB实现AOP?
6.Spring在选择用JDK还是CGLiB的依据是什么?CGlib比JDK快?
8.Spring中解决循环依赖为什么要用三级缓存,二级为什么不行呢?
9.spring能解决那些循环依赖、不能解决那些循环依赖,为什么?
10.Spring注入bean的方式有哪些(列举下你使用过的注入Bean的方式)?
12.BeanFactory和ApplicationContext的联系和区别
14.Spring的@Transactional如何实现的(必考)
19.Spring Cloud Zuul网关的调优策略有哪些?怎么实现其高可用?Zuul和Gataway,你们项目中是怎么选择的?项目中对Zuul网关层的要求是什么样的?
20.Spring Cloud Eureka和Nacos对比?怎么做选择?Eureka中高可用是怎么做的?进行的调优有哪些?原理是什么?
21.Spring Cloud 中常用的注解有哪些?怎么用的?
22.Spring Cloud中的组件有哪些?具体说说?微服务架构中用到的关键技术有哪些?
23.Spring Cloud Config配置架构是什么样的?可视化怎么做的?设计的业务有哪些?
干货分享,感谢您的阅读!备注:针对基本问题做一些基本的总结,不是详细解答!
Spring开发WEB应用程序过程广泛采用的固定开发模式:通常包括使用Maven、Gradle等工具搭建工程、web.xml定义Spring的DispatcherServlet、完成启动Spring MVC的配置文件、编写响应HTTP请求的Controller以及服务部署到Tomcat Web服务器等步骤。但是,基于传统Spring框架进行开发的开发过程中,逐渐暴露出一些问题,典型的就是过于复杂和繁重的配置工作。
Spring Boot优化了开发过程,采用约定优于配置思想的自动化配置、启动依赖项目自动管理、简化部署并提供监控等功能,是开发过程变得简单。其核心优势体现在编码、配置、部署、监控等多个方面:
Spring Boot通常有一个名为*Application的入口类,在入口类里有一个main方法,这个main方法其实就是一个标准的java应用的入口方法。在main方法中使用SpringApplication.run方法启动SpringBoot应用项目。
其中@SpringBootApplication是Spring Boot的核心注解,主要组合了@Configuration、@EnableAutoConfiguration、@ComponentScan。(如果不使用@SpringBootApplication注解,则可以使用在入口类上直接使用@Configuration、@EnableAutoConfiguration、@ComponentScan也能达到相同效果。)
其中几个注解的作用大致说一下:
spring-boot启动过程:
在这个静态方法中,创建并构造了SpringApplication对象,并调用该对象的run方法。
构造SpringApplication对象:主要是对一些属性附上初始值,关键在与SpringApplication对象的initialize方法。
deduceWebEnvironment
来判断当前的应用是否是web应用,并设置到webEnvironment
属性中。getSpringFactoriesInstances
从spring.factories文件中找出key为ApplicationContextInitializer的类并实例化,然后调用setInitializers
方法设置到SpringApplication
的initializers
属性中。getSpringFactoriesInstances
从spring.factories文件中找出key为ApplicationListener的类并实例化,然后调用setListeners
方法设置到SpringApplication
的listeners
属性中。deduceMainApplicationClass
方法找出main类初始化SpringApplication完成之后,调用run
方法运行,run方法执行完成之后,Spring容器也已经初始化完成,各种监听器和初始化器也做了相应的工作。
具体详细如下:
AOP的实现方式:动态代理的实现方式
实现方式有两种:JDK动态代理和CGLIB动态代理
何时使用JDK还是CGLiB?
如何强制使用CGLIB实现AOP?
Spring在选择用JDK还是CGLiB的依据:
CGlib比JDK快?
使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,在jdk6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
在jdk6、jdk7、jdk8逐步对JDK动态代理优化之后,在调用次数较少的情况下,JDK代理效率高于CGLIB代理效率,只有当进行大量调用的时候,jdk6和jdk7比CGLIB代理效率低一点,但是到jdk8的时候,jdk代理效率高于CGLIB代理,总之,每一次jdk版本升级,jdk代理效率都得到提升,而CGLIB代理消息确有点跟不上步伐。
Spring使用三级缓存(三级缓存是指singletonObjects、earlySingletonObjects和singletonFactories)来解决循环依赖的问题。
下面是Spring如何解决循环依赖的简要过程:
总结起来,Spring通过三级缓存的机制,在Bean创建的过程中提前暴露引用并暂停创建,以解决循环依赖的问题。这种机制允许Spring容器在循环依赖的情况下正确地管理Bean的创建顺序,并确保每个Bean都可以获取到正确的依赖实例。
在Spring框架中解决循环依赖问题时,使用三级缓存(三级缓存指的是singletonFactories、earlySingletonObjects和singletonObjects)是为了确保在循环依赖情况下能够正确地获取到完整的Bean对象。
为了更好地理解为什么需要三级缓存而不是二级缓存,让我们简要回顾一下Spring解决循环依赖的过程:
现在回到你的问题,为什么二级缓存(即earlySingletonObjects)不能满足解决循环依赖的需求?
在循环依赖的场景中,两个Bean相互依赖,即A依赖于B,同时B也依赖于A。如果只使用二级缓存,当创建Bean A时,它会从二级缓存(earlySingletonObjects)中获取Bean B的引用,但是Bean B此时可能尚未完全初始化,只是一个尚未初始化的对象。这样,当Bean A依赖于Bean B的某些属性或方法时,可能会出现空指针异常或不完整的对象状态。
为了避免这种情况,Spring使用三级缓存。在三级缓存中,当Bean A创建时,它会从singletonFactories缓存中获取Bean B的创建工厂,并将其作为未完全初始化的Bean对象暴露给Bean B。当Bean B需要引用Bean A时,它可以从earlySingletonObjects缓存中获取到已经创建但尚未完全初始化的Bean A。这样可以确保在循环依赖的情况下,每个Bean都能够获取到一个完整的但尚未初始化的引用,从而避免了循环依赖的问题。
因此,使用三级缓存是为了保证在循环依赖场景下的Bean获取的正确性和完整性。二级缓存(earlySingletonObjects)只提供了尚未完全初始化的Bean对象的引用,而无法确保完整的Bean状态。
Spring能够解决的循环依赖情况:
Spring不能解决的循环依赖情况:
总结起来,Spring可以解决构造函数和setter方法的循环依赖情况,但无法解决单例Bean和原型Bean之间的循环依赖。这是因为单例Bean在启动时创建,无法进行延迟初始化,而原型Bean的创建是每次请求时进行的,无法通过缓存来解决循环依赖。在设计应用程序时,应避免出现循环依赖,以减少潜在的问题。
Spring提供了多种注入Bean的方式,以下是一些常用的注入方式:
在我使用过的注入Bean的方式中,我主要使用了构造函数注入和Setter方法注入。构造函数注入常用于必须的依赖,而Setter方法注入则用于可选的依赖或需要动态变化的依赖。这两种方式都可以通过@Autowired注解来实现依赖注入。
在Spring框架中,后置处理器(PostProcessor)是一种特殊的Bean,用于在容器中创建和配置其他Bean时进行干预和定制。后置处理器可以在Bean的实例化、属性填充和初始化等阶段介入,并对Bean进行修改、增强或扩展功能。
Spring框架提供了多个后置处理器接口,其中最常用的是BeanPostProcessor接口。其定义了两个核心方法:
通过实现BeanPostProcessor接口,可以在Bean的初始化前后执行一些自定义逻辑,例如在Bean初始化后添加某些功能、修改属性值、应用AOP切面等。另外,Spring还提供了其他的后置处理器接口,例如BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,它们分别用于处理Bean定义和Bean工厂的配置。
使用后置处理器可以实现以下功能:
需要注意的是,使用后置处理器要谨慎,因为它们会对容器中的所有Bean进行处理,可能会对系统的性能产生一定的影响。因此,在使用后置处理器时,应该确保逻辑简洁高效,并仅对需要进行特殊处理的Bean进行干预。
BeanFactory和ApplicationContext都是Spring框架中用于管理和获取Bean的核心接口,它们有联系和区别如下:
联系:
区别:
总结起来,BeanFactory是Spring框架的基础接口,提供了基本的Bean管理功能;而ApplicationContext是对BeanFactory的扩展,提供了更多的高级功能和企业级特性。在实际应用中,ApplicationContext更常用,因为它提供了更多的便利和功能,并且通常能够满足大多数应用场景的需求。
Spring事务是Spring框架提供的一种机制,用于管理数据库操作或其他资源访问的一系列操作,以保证数据的一致性和可靠性。事务的概念是指一组操作被视为一个不可分割的工作单元,要么全部成功提交,要么全部回滚,以确保数据的完整性。
以下是对Spring事务的一些理解:
Spring事务的设计目标是提供一种灵活、可扩展和易用的事务管理机制,使开发者能够轻松地实现和管理事务,确保数据操作的一致性和可靠性。通过Spring的事务管理,开发者可以专注于业务逻辑的实现,而无需过多关注底层事务管理的细节。
@Transactional是spring中声明式事务管理的注解配置方式,@Transactional注解可以帮助我们把事务开启、提交或者回滚的操作,通过aop的方式进行管理。通过@Transactional注解就能让spring为我们管理事务,免去了重复的事务管理逻辑,减少对业务代码的侵入,使我们开发人员能够专注于业务层面开发。
实现@Transactional原理是基于spring aop,aop又是动态代理模式的实现。主要源码如下:
事务传播行为(为了解决业务层方法之间互相调用的事务问题):当事务方法被另一个事务方法调用时,必须指定事务应该如何传播
例如:方法可能继续在现有事务中运行,也可能开启一个新事务并在自己的事务中运行。
在TransactionDefinition定义中包括了如下几个表示传播行为的常量:
支持当前事务的情况:
不支持当前事务的情况:
其他情况:
TransactionDefinition 接口中定义了五个表示隔离级别的常量:
以下是一些可能导致Spring事务失效的场景:
为了避免Spring事务失效,需要注意以上场景,并合理配置和使用事务管理器、事务注解和事务传播行为。同时,了解事务的特性和使用方式,以及特定场景下的注意事项,可以帮助保证事务的正确应用和有效性。
事务失效的原因可能包括以下几个方面:
了解这些原因可以帮助开发者在使用Spring事务时注意相关细节,合理配置事务管理器和事务注解,并确保事务在应用中正确生效和回滚,以保证数据操作的一致性和可靠性。
Spring Cloud Zuul网关的调优策略
Zuul 1.0 是一个基于JVM的后端路由器,同时是一个建立在Servlet上的同步阻塞架构,故在使用时对这部分的优化工作是必要的,根据实践经验,对Zuul的优化分为以下几个类型:
高可用方案
Spring Cloud Zuul网关高可用可以借助OpenResty整合的Nginx和Lua,使用Lua脚本模块与注册中心构建一个服务动态增减的机制,通过Lua获取注册中心状态为UP的服务,动态地加入到Nginx的负载均衡列表中,将其称之为“多层负载”。
其实也可以结合K8S特性去实现,这个之前玩K8S的时候试验过,是可以实现的!
Zuul和Gataway对比和选择
从底层源码上来看,Zuul构建于 Servlet 2.5,兼容 3.x,使用的是阻塞式的 API,不支持长连接,比如 websockets。另外
Spring Cloud Gateway构建于 Spring 5+,基于 Spring Boot 2.x 响应式的、非阻塞式的 API。同时,它支持 websockets,和 Spring 框架紧密集成,开发体验相对来说十分不错。
在微服务架构中网关上的选择,最好的方式是使用现在比较成熟的Spring Cloud套件,Zuul和Gataway都可以,最好提供了Spring Cloud Gateway网关,或是结合公司情况来开发一套适合自己的微服务套件,至少从网关上可以看出来其内部实现并不难,同时也比较期待开源项目Nacos、Spring Cloud Alibaba 建设情况,期待它能构建一个高活跃社区的、稳定的、适合中国特色(大流量、高并发)的微服务基础架构。
项目中对网关的要求
基本具备以下功能:认证和鉴权+压力控制+金丝雀测试+动态路由+负载均衡+静态响应处理+主动流量控制+限流+文件上传+参数转换+其他逻辑与业务处理等。
都是服务注册发现中心,但是Nacos还可以用作配置中心,目前来看,建议使用Nacos,因为Eureka已经不在开源,而且性能上和高可用上没有Nacos方便。
相关调优方案见上面的博客。
在介绍Spring Cloud 全家桶之前,首先要介绍一下Netflix ,Netflix 是一个很伟大的公司,在Spring Cloud项目中占着重要的作用,Netflix 公司提供了包括Eureka、Hystrix、Zuul、Archaius等在内的很多组件,在微服务架构中至关重要,Spring在Netflix 的基础上,封装了一系列的组件。
关键技术及要求基本有:
微服务架构-实现技术之六大基础组件:服务通信+事件驱动+负载均衡+服务路由+API网关+配置管理
微服务架构-实现技术之三大关键要素1服务治理:服务注册中心+服务发布与注册+服务发现与调用+服务监控
微服务架构-实现技术之三大关键要素2数据一致性:分布式事物+CAP&BASE+可靠事件模式+补偿模式+Sagas模式+TCC模式+最大努力通知模式+人工干预模式
微服务架构-实现技术之三大关键要素3服务可靠性:服务访问失败的原因和应对策略+服务容错+服务隔离+服务限流+服务降级
1.SpringBoot启动过程 | wangqi的blog Spring Boot启动加载过程讲的很详细
2.微服务架构-实现技术之具体实现工具与框架2:Spring Boot概览与核心原理_张彦峰ZYF的博客-CSDN博客
3.Spring Boot 学习笔记一(SpringBoot启动过程)_小沙弥修BUG的博客-CSDN博客
4.https://www.cnblogs.com/liubin1988/p/8909610.html
5.Java动态代理详解:JDK和CGLIB的区别和实现_Yanyan.He的博客-CSDN博客 动态代理的举例
6.https://www.cnblogs.com/wangenxian/p/10885309.html
7.https://www.cnblogs.com/gonjan-blog/p/6685611.html
8.Spring源码初探-IOC(4)-Bean的初始化-循环依赖的解决 - 简书
9.spring源码阅读--@Transactional实现原理_@transactional原理_一撸向北的博客-CSDN博客
10.Spring @Transactional工作原理详解_Java_软件编程 - 编程客栈
12.https://www.cnblogs.com/chongaizhen/p/11003832.html
13.https://blog.csdn.net/xiaofeng10330111/article/details/87272495
14.Spring Cloud Gateway VS Zuul 比较,怎么选择?_Java技术栈的博客-CSDN博客
15.微服务网关Zuul和Gateway的区别_gateway和zuul的区别与联系_莫明的编织者的博客-CSDN博客
16.Spring Cloud 常用注解注解_springcloud 常用注解_-Se7ven的博客-CSDN博客
17.微服务架构-实现技术之具体实现工具与框架4:Spring Cloud Eureka原理与注意事项_张彦峰ZYF的博客-CSDN博客
18.Spring Cloud全家桶主要组件及简要介绍_springcloud五大组件_徐刘根的博客-CSDN博客
19.【第二章】 IoC 之 2.1 IoC基础 ——跟我学Spring3 - 《亿级流量网站架构核心技术》~ - ITeye博客
20.百度安全验证
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。