前言
文本已收录至我的 GitHub 仓库,欢送 Star:https://github.com/bin3923282…
种一棵树最好的工夫是十年前,其次是当初
Tips
面试指南系列,很多状况下不会去深挖细节,是小六六以被面试者的角色去回顾常识的一种形式,所以我默认大部分的货色,作为面试官的你,必定是懂的。
https://www.processon.com/vie…
下面的是脑图地址
叨絮
SSM 框架,这个是咱们平时用的最多的,所以面试中也是常常被问到,明天咱们就来看看这几个框架呗
而后上面是后面的文章汇总
- 2021-Java 后端工程师面试指南 -(引言)
- 2021-Java 后端工程师面试指南 -(Java 根底篇)
- 2021-Java 后端工程师面试指南 -(并发 - 多线程)
- 2021-Java 后端工程师面试指南 -(JVM)
- 2021-Java 后端工程师面试指南 -(MySQL)
- 2021-Java 后端工程师面试指南 -(Redis)
- 2021-Java 后端工程师面试指南 -(Elasticsearch)
- 2021-Java 后端工程师面试指南 -(音讯队列)
什么是 Spring
Spring 是一种轻量级开发框架,旨在进步开发人员的开发效率以及零碎的可维护性。咱们个别说 Spring 框架指的都是 Spring Framework,它是很多模块的汇合,应用这些模块能够很不便地帮助咱们进行开发。这些模块是:外围容器、数据拜访 / 集成,、Web、AOP(面向切面编程)、工具、音讯和测试模块。比方:Core Container 中的 Core 组件是 Spring 所有组件的外围,Beans 组件和 Context 组件是实现 IOC 和依赖注入的根底,AOP 组件用来实现面向切面编程。
谈谈本人对于 Spring IoC 和 AOP 的了解
IoC(Inverse of Control: 管制反转)是一种设计思维,就是 将本来在程序中手动创建对象的控制权,交由 Spring 框架来治理。IoC 在其余语言中也有利用,并非 Spring 特有。IoC 容器是 Spring 用来实现 IoC 的载体,IoC 容器实际上就是个 Map(key,value),Map 中寄存的是各种对象。
将对象之间的相互依赖关系交给 IoC 容器来治理,并由 IoC 容器实现对象的注入。这样能够很大水平上简化利用的开发,把利用从简单的依赖关系中解放出来。IoC 容器就像是一个工厂一样,当咱们须要创立一个对象的时候,只须要配置好配置文件 / 注解即可,齐全不必思考对象是如何被创立进去的。在理论我的项目中一个 Service 类可能有几百甚至上千个类作为它的底层,如果咱们须要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只须要配置好,而后在须要的中央援用就行了,这大大增加了我的项目的可维护性且升高了开发难度。
AOP(Aspect-Oriented Programming: 面向切面编程)可能将那些与业务无关,却为业务模块所独特调用的逻辑或责任(例如事务处理、日志治理、权限管制等)封装起来,便于缩小零碎的反复代码,升高模块间的耦合度,并有利于将来的可拓展性和可维护性。
Spring AOP 就是基于动静代理的,如果要代理的对象,实现了某个接口,那么 Spring AOP 会应用 JDK Proxy,去创立代理对象,而对于没有实现接口的对象,就无奈应用 JDK Proxy 去进行代理了,这时候 Spring AOP 会应用 Cglib,这时候 Spring AOP 会应用 Cglib 生成一个被代理对象的子类来作为代理.
个别咱们能够应用 AspectJ ,Spring AOP 曾经集成了 AspectJ,AspectJ 应该算的上是 Java 生态系统中最残缺的 AOP 框架了。
应用 AOP 之后咱们能够把一些通用性能形象进去,在须要用到的中央间接应用即可,这样大大简化了代码量。咱们须要减少新性能时也不便,这样也进步了零碎扩展性。日志性能、事务管理等等场景都用到了 AOP。
那你聊聊 Spring AOP 和 AspectJ AOP 有什么区别?平时在我的项目中你个别用的哪个
Spring AOP 属于运行时加强,而 AspectJ 是编译时加强。Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。
Spring AOP 曾经集成了 AspectJ,AspectJ 应该算的上是 Java 生态系统中最残缺的 AOP 框架了。AspectJ 相比于 Spring AOP 性能更加弱小,然而 Spring AOP 相对来说更简略,
咱们个别在我的项目中用的 AspectJ AoP 比拟多点
Spring 的 bean 作用域(scope)类型,Spring Bean 是否是线程平安的
Spring 容器中的 Bean 是否线程平安,容器自身并没有提供 Bean 的线程安全策略,因而能够说 Spring 容器中的 Bean 自身不具备线程平安的个性,然而具体还是要联合具体 scope 的 Bean 去钻研。
Spring 的 bean 作用域(scope)类型
- singleton: 单例,默认作用域。
- prototype: 原型,每次创立一个新对象。
- request: 申请,每次 Http 申请创立一个新对象,实用于 WebApplicationContext 环境下。
- session: 会话,同一个会话共享一个实例,不同会话应用不必的实例。
线程平安这个问题,要从单例与原型 Bean 别离进行阐明。
- 对于原型 Bean, 每次创立一个新对象,也就是线程之间并不存在 Bean 共享,天然是不会有线程平安的问题。
- 对于单例 Bean, 所有线程都共享一个单例实例 Bean, 因而是存在资源的竞争。
- 如果单例 Bean, 是一个无状态 Bean,也就是线程中的操作不会对 Bean 的成员执行查问以外的操作,那么这个单例 Bean 是线程平安的。比方 Spring mvc 的 Controller、Service、Dao 等,这些 Bean 大多是无状态的,只关注于办法自身。
总结下
- 在 @Controller/@Service 等容器中,默认状况下,scope 值是单例 -singleton 的,也是线程不平安的。
- 尽量不要在 @Controller/@Service 等容器中定义动态变量,不论是单例 (singleton) 还是多实例 (prototype) 他都是线程不平安的。
- 默认注入的 Bean 对象,在不设置 scope 的时候他也是线程不平安的。
- 肯定要定义变量的话,用 ThreadLocal 来封装,这个是线程平安的
那你说说 @Component 和 @Bean 的区别是什么?
- 作用对象不同: @Component 注解作用于类,而 @Bean 注解作用于办法。
- @Component 通常是通过类门路扫描来主动侦测以及主动拆卸到 Spring 容器中(咱们能够应用 @ComponentScan 注解定义要扫描的门路从中找出标识了须要拆卸的类主动拆卸到 Spring 的 bean 容器中)。@Bean 注解通常是咱们在标有该注解的办法中定义产生这个 bean,@Bean 通知了 Spring 这是某个类的示例,当我须要用它的时候还给我。
- @Bean 注解比 Component 注解的自定义性更强,而且很多中央咱们只能通过 @Bean 注解来注册 bean。比方当咱们援用第三方库中的类须要拆卸到 Spring 容器时,则只能通过 @Bean 来实现。
那你聊聊什么是 spring 拆卸,主动拆卸有哪些形式?
当 bean 在 Spring 容器中组合在一起时,它被称为拆卸或 bean 拆卸。Spring 容器须要晓得须要什么 bean 以及容器应该如何应用依赖注入来将 bean 绑定在一起,同时拆卸 bean。
Spring 容器可能主动拆卸 bean。也就是说,能够通过查看 BeanFactory 的内容让 Spring 主动解析 bean 的协作者。
主动拆卸的不同模式:
- no – 这是默认设置,示意没有主动拆卸。应应用显式 bean 援用进行拆卸。
- byName – 它依据 bean 的名称注入对象依赖项。它匹配并拆卸其属性与 XML 文件中由雷同名称定义的 bean。
- byType – 它依据类型注入对象依赖项。如果属性的类型与 XML 文件中的一个 bean 名称匹配,则匹配并拆卸属性。
- 构造函数 – 它通过调用类的构造函数来注入依赖项。它有大量的参数。
- autodetect – 首先容器尝试通过构造函数应用 autowire 拆卸,如果不能,则尝试通过 byType 主动拆卸。
你晓得 @Autowired 注解有什么用?那 @Qualifier 呢?
- @Autowired 能够更精确地管制应该在何处以及如何进行主动拆卸。此注解用于在 setter 办法,构造函数,具备任意名称或多个参数的属性或办法上主动拆卸 bean。默认状况下,它是类型驱动的注入。
- 当您创立多个雷同类型的 bean 并心愿仅应用属性拆卸其中一个 bean 时,您能够应用 @Qualifier 注解和 @Autowired 通过指定应该拆卸哪个确切的 bean 来打消歧义。
说说 Spring Bean 的生命周期
精确的理解 Spring Bean 的生命周期是十分必要的。咱们通常应用 ApplicationContext 作为 Spring 容器。这里,咱们讲的也是 ApplicationContext 中 Bean 的生命周期。而实际上 BeanFactory 也是差不多的,只不过处理器须要手动注册。
其实在整个 Bean 的生命周期,也就是 Bean 初始化实现之前,咱们的 spring 给咱们提供了太多的拓展点了,能够让咱们灵便的去解决咱们不同的需要,上面来总结总结这些钩子函数
Bean 的残缺生命周期经验了各种办法调用,这些办法能够划分为以下几类:
- Bean 本身的办法:这个包含了 Bean 自身调用的办法和通过配置文件中 <bean> 的 init-method 和 destroy-method 指定的办法
- Bean 级生命周期接口办法:这个包含了 BeanNameAware、BeanFactoryAware、InitializingBean 和 DiposableBean 这些接口的办法
- 容器级生命周期接口办法:这个包含了 InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,个别称它们的实现类为“后处理器”。
聊聊 Web 容器的启动过程吧,说说它的启动形式
首先咱们来聊聊 Spring 容器的启动形式,也就是咱们整个 web 我的项目的一个启动形式,目前支流的公司个别分为 2 种,一种基于 ssm 的启动流程,一种是基于 SpringBoot 的启动过程,明天我就来说说 ssm 的一个启动流程,springboot 的下次和 springcloud 系列一起讲
SSM 的 SpringBoot 的启动流程
- 首先,对于一个 web 利用,其部署在 web 容器中,web 容器提供其一个全局的上下文环境,这个上下文就是 ServletContext,其为前面的 spring IoC 容器提供宿主环境;
- 而后就是咱们的 web.xml,在几年前的我的项目我想大家都有碰到过吧,在 web.xml 中会提供有 contextLoaderListener。在 web 容器启动时,会触发容器初始化事件,此时 contextLoaderListener 会监听到这个事件,其 contextInitialized 办法会被调用,在这个办法中,spring 会初始 化一个启动上下文,这个上下文被称为根上下文,即 WebApplicationContext,这是一个接口类,确切的说,其理论的实现类是 XmlWebApplicationContext。这个就是 spring 的 IoC 容器,其对应的 Bean 定义的配置由 web.xml 中的 context-param 标签指定。在这个 IoC 容器初始化结束后,spring 以 WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE 为属性 Key,将其存储到 ServletContext 中,便于获取;
- 再 次,contextLoaderListener 监听器初始化结束后,开始初始化 web.xml 中配置的 Servlet,这里是 DispatcherServlet,这个 servlet 实际上是一个规范的前端控制器,用以转发、匹配、解决每个 servlet 请 求。DispatcherServlet 上下文在初始化的时候会建设本人的 IoC 上下文,用以持有 spring mvc 相干的 bean。在建设 DispatcherServlet 本人的 IoC 上下文时,会利用 WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE 先从 ServletContext 中获取之前的根上下文 (即 WebApplicationContext) 作为本人上下文的 parent 上下文。有了这个 parent 上下文之后,再初始化本人持有的上下文。这个 DispatcherServlet 初始化本人上下文的工作在其 initStrategies 方 法中能够看到,大略的工作就是初始化处理器映射、视图解析等。这个 servlet 本人持有的上下文默认实现类也是 XmlWebApplicationContext。初始化结束后,spring 以与 servlet 的名字相干 (此处不是简略的以 servlet 名为 Key,而是通过一些转换,具体可自行查看源码) 的属性为属性 Key,也将其存到 ServletContext 中,以便后续应用。这样每个 servlet 就持有本人的上下文,即领有本人独立的 bean 空间,同时各个 servlet 共享雷同的 bean,即根上下文 (第 2 步中初始化的上下文) 定义的那些 bean。
下面就是咱们整个 SSM 的启动过程了,也是几年前大多数企业级开发的一个整个我的项目启动流程哦,至于 SpringBoot 的形式,下一篇 springboot 再在
那你聊聊 Spring 容器的加载过程呗(ioc 的启动流程)
下面的过程是整个 web 容器的启动过程,它外面蕴含了咱们 spring 容器的启动流程,我当初就给大家具体的解说咱们 ioc 启动的加载过程
AbstractApplicationContext.java 里的 refresh() 办法,这个办法就是构建整个 IoC 容器过程的残缺代码,只有把这个办法里的每一行代码都理解了,基本上理解了大部分 ioc 的原理和性能。
- prepareRefresh() 办法:为刷新筹备新的上下文环境,设置其启动日期和流动标记以及执行一些属性的初始化。次要是一些筹备工作,不是很重要的办法,能够先不关注
-
obtainFreshBeanFactory() 办法:该办法会解析所有 Spring 配置文件(通常咱们会放在 resources 目录下),将所有 Spring 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory 中。常见的,如果解析到 <context:component-scan base-package=”com.joonwhee.open” /> 注解时,会扫描 base-package 指定的目录,将该目录下应用指定注解(@Controller、@Service、@Component、@Repository)的 bean 定义也同样封装成 BeanDefinition,加载到 BeanFactory 中。下面提到的“加载到 BeanFactory 中”的内容次要指的是以下 3 个缓存:
- beanDefinitionNames 缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 汇合。
- beanDefinitionMap 缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和 BeanDefinition 映射。
- aliasMap 缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和别名映射。
- prepareBeanFactory(beanFactory) 办法:配置 beanFactory 的规范上下文特色,例如上下文的 ClassLoader、后置处理器等。这个办法会注册 3 个默认环境 bean:environment、systemProperties 和 systemEnvironment,注册 2 个 bean 后置处理器:ApplicationContextAwareProcessor 和 ApplicationListenerDetector。
- postProcessBeanFactory(beanFactory) 办法:容许子类对 BeanFactory 进行后续解决,默认实现为空,留给子类实现。
- invokeBeanFactoryPostProcessors(beanFactory) 办法:实例化和调用所有 BeanFactoryPostProcessor,包含其子类 BeanDefinitionRegistryPostProcessor。
- registerBeanPostProcessors(beanFactory) 办法:注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。
- initMessageSource() 办法:初始化音讯资源 MessageSource
- initApplicationEventMulticaster() 办法: 初始化利用的事件播送器 ApplicationEventMulticaster。
- onRefresh() 办法: 该办法为模板办法,提供给子类扩大实现,能够重写以增加特定于上下文的刷新工作,默认实现为空。(在 springboot 中这个办法可是加载 tomcat 容器的)
- registerListeners() 办法:注册监听器。
- finishBeanFactoryInitialization(beanFactory) 办法:该办法会实例化所有残余的非懒加载单例 bean。除了一些外部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其余的非懒加载单例 bean 都会在这个办法中被实例化,并且 BeanPostProcessor 的触发也是在这个办法中。(这个办法其实是外围办法了,蕴含咱们的 bea 从 beandifinition 变成咱们的容器中的 bean 最外围的办法了)
- finishRefresh() 办法:实现此上下文的刷新,次要是推送上下文刷新结束事件(ContextRefreshedEvent)到监听器。
比拟重要的是上面几个点
- obtainFreshBeanFactory 创立一个新的 BeanFactory、读取和解析 bean 定义。
- invokeBeanFactoryPostProcessors 提供给开发者对 BeanFactory 进行扩大。
- registerBeanPostProcessors 提供给开发者对 bean 进行扩大。
- finishBeanFactoryInitialization 实例化残余的所有非懒加载单例 bean。
SpringMVC 工作原理理解吗? 基于页面 Controller 的类型
- 客户端(浏览器)发送申请,间接申请到 DispatcherServlet。
- DispatcherServlet 依据申请信息调用 HandlerMapping,解析申请对应的 Handler。
- 解析到对应的 Handler(也就是咱们平时说的 Controller 控制器)后,开始由 HandlerAdapter 适配器解决。
- HandlerAdapter 会依据 Handler 来调用真正的处理器来解决申请,并解决相应的业务逻辑。
- 处理器解决完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。
- ViewResolver 会依据逻辑 View 查找理论的 View。
- DispaterServlet 把返回的 Model 传给 View(视图渲染)。
- 把 View 返回给请求者(浏览器)
聊聊 Spring 框架中用到了哪些设计模式?
- 工厂设计模式 : Spring 应用工厂模式通过 BeanFactory、ApplicationContext 创立 bean 对象。
- 代理设计模式 : Spring AOP 性能的实现。
- 单例设计模式 : Spring 中的 Bean 默认都是单例的。
- 模板办法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就应用到了模板模式。
- 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个利用。
- 适配器模式 :Spring AOP 的加强或告诉 (Advice) 应用到了适配器模式、spring MVC 中也是用到了适配器模式适配 Controller。
spring 事务相熟不,个别你用哪种实现形式
- 编程式事务,在代码中硬编码。(不举荐应用)
- 申明式事务,在配置文件中配置(举荐应用)
个别在咱们企业级开发的过程中,个别都是用的申明式事务,申明式事务也分为 2 种一种是基于 xml 的,一种基于注解的,个别用注解的多点
说说 Spring 事务中哪几种事务流传行为?
反对以后事务的状况:
- TransactionDefinition.PROPAGATION_REQUIRED:如果以后存在事务,则退出该事务;如果以后没有事务,则创立一个新的事务。
- TransactionDefinition.PROPAGATION_SUPPORTS:如果以后存在事务,则退出该事务;如果以后没有事务,则以非事务的形式持续运行。
- TransactionDefinition.PROPAGATION_MANDATORY:如果以后存在事务,则退出该事务;如果以后没有事务,则抛出异样。(mandatory:强制性)
不反对以后事务的状况:
- TransactionDefinition.PROPAGATION_REQUIRES_NEW:创立一个新的事务,如果以后存在事务,则把以后事务挂起。
- TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务形式运行,如果以后存在事务,则把以后事务挂起。
- TransactionDefinition.PROPAGATION_NEVER:以非事务形式运行,如果以后存在事务,则抛出异样。
说说 BeanFactory 和 FactoryBean 的区别?
- BeanFactory 是个 Factory,也就是 IOC 容器或对象工厂,在 Spring 中,所有的 Bean 都是由 BeanFactory(也就是 IOC 容器)来进行治理的,提供了实例化对象和拿对象的性能。
- FactoryBean 是个 Bean,这个 Bean 不是简略的 Bean,而是一个能生产或者润饰对象生成的工厂 Bean, 它的实现与设计模式中的工厂模式和润饰器模式相似。
聊聊 Spring 的循环依赖吧
- spring 的循环依赖次要是指两个类相互之间通过 @Autowired 主动依赖注入对方,即类 A 蕴含一个类 B 的对象援用并须要主动注入,类 B 蕴含一个类 A 的对象援用也须要主动注入。
- 对于循环依赖问题,spring 依据注入形式的不同,采取不同的解决策略,对于单方都是应用属性值注入或者 setter 办法注入,则 spring 能够主动解决循环依赖注入问题,应用程序能够胜利启动;对于单方都是应用构造函数注入对方或者主 bean 对象(Spring 在启动过程中,先加载的 bean 对象)应用构造函数注入,则 spring 无奈解决循环依赖注入,程序报错无奈启动。
首先 spring 在单例的状况下是默认反对循环援用的;在不做任何配置的状况下,两个 bean 相互依赖是能初始化胜利的;spring 源码中在创立 bean 的时候先创立这个 bean 的对象,创建对象实现之后通过判断容器对象的 allowCircularReferences 属性决定是否容许缓存这个长期对象,如果能被缓存胜利则通过缓存提前裸露这个长期对象来实现循环依赖;而这个属性默认为 true,所以说 spring 默认反对循环依赖的,然而这个属性 spring 提供了 api 让程序员来批改,所以 spring 也提供了敞开循环援用的性能;
那你说说 Spring 是如何解决循环援用的
首先,Spring 外部保护了三个 Map,也就是咱们通常说的三级缓存。
笔者翻阅 Spring 文档倒是没有找到三级缓存的概念,可能也是外乡为了不便了解的词汇。
在 Spring 的 DefaultSingletonBeanRegistry 类中,你会赫然发现类上方挂着这三个 Map:
- singletonObjects 它是咱们最相熟的敌人,俗称“单例池”“容器”,缓存创立实现单例 Bean 的中央。
- singletonFactories 映射创立 Bean 的原始工厂
- earlySingletonObjects 映射 Bean 的晚期援用,也就是说在这个 Map 里的 Bean 不是残缺的,甚至还不能称之为“Bean”,只是一个 Instance.
后两个 Map 其实是“垫脚石”级别的,只是创立 Bean 的时候,用来借助了一下,创立实现就清掉了。
所以笔者前文对“三级缓存”这个词有些蛊惑,可能是因为正文都是以 Cache of 结尾吧。
为什么成为后两个 Map 为垫脚石,假如最终放在 singletonObjects 的 Bean 是你想要的一杯“凉白开”。
那么 Spring 筹备了两个杯子,即 singletonFactories 和 earlySingletonObjects 来回“倒腾”几番,把热水晾成“凉白开”放到 singletonObjects 中。
循环援用的不同的场景,有哪些办法能够解决循环援用
为啥有些注入形式不能解决循环依赖问题呢?源码中看出,他们并没有用到那个 earlySingletonObjects 这个缓存,所以就不能解决循环依赖
解决 Spring 无奈解决的循环依赖的一些形式
我的项目中如果呈现循环依赖问题,阐明是 spring 默认无奈解决的循环依赖,要看我的项目的打印日志,属于哪种循环依赖。目前蕴含上面几种状况:
生成代理对象产生的循环依赖
这类循环依赖问题解决办法很多,次要有:
- 应用 @Lazy 注解,提早加载
- 应用 @DependsOn 注解,指定加载先后关系
- 批改文件名称,扭转循环依赖类的加载程序
说说什么是 Mybatis?
- Mybatis 是一个半 ORM(对象关系映射)框架,它外部封装了 JDBC,加载驱动、创立连贯、创立 statement 等繁冗的过程,开发者开发时只须要关注如何编写 SQL 语句,能够严格控制 sql 执行性能,灵便度高。
- 作为一个半 ORM 框架,MyBatis 能够应用 XML 或注解来配置和映射原生信息,将 POJO 映射成数据库中的记录,防止了简直所有的 JDBC 代码和手动设置参数以及获取后果集。
说说 #{}和 ${}的区别是什么?
-
{}是预编译解决,${}是字符串替换。
- Mybatis 在解决 #{}时,会将 sql 中的#{}替换为? 号,调用 PreparedStatement 的 set 办法来赋值;
- Mybatis 在解决 ${}时,就是把 ${}替换成变量的值。
- 应用 #{}能够无效的避免 SQL 注入,进步零碎安全性。
说说 Mybatis 的一级、二级缓存:
一级缓存 事务范畴:缓存只能被以后事务拜访。缓存的生命周期 依赖于事务的生命周期当事务完结时,缓存也就完结生命周期。在此范畴下,缓存的介质是内存。二级缓存 过程范畴:缓存被过程内的所有事务共享。这些事务有 可能是并发拜访缓存,因而必须对缓存采取必要的事务隔离机制。缓存的生命周期依赖于过程的生命周期,过程完结时,缓存也就完结了生命周期。过程范畴的缓存可能会寄存大量的数据,所以寄存的介质能够是内存或硬盘。
聊聊 Mybatis 的一个整体的架构吧
其实哈,我感觉 mybatis 框架次要须要做的事件咱们是晓得的,为啥呢?因为其实如果咱们没有 mybatis 咱们也能够做数据库操作对吧,那就是 jdbc 的操作呗,那其实 mybatis 就是在封装在 jdbc 之上的一个框架而已,它所须要做的就是那么多,我来总结下
- 首先就是一些根底组件 连贯治理,事务管理,配置的加载,缓存的解决
- 而后是外围的性能,咱们参数映射,咱们的 sql 解析,sql 执行,咱们的后果映射
- 之上就是封装咱们对立的 crud 接口就好了,对就这么多咯。
下面就是整个 mybatis 做的事件了,当然每一块性能解决起来也是不那么简略的。
对 Mybatis 的源码相熟吗,找你相熟的中央聊聊呗
下面的图是整个 mybatis 的一个外围流程,其实不过是 spring 也好,mybatis 也好,所有的框架咱们都能够把他们分为 2 个局部,一个就是初始化的过程,就是相当于做好筹备工作来接客的过程,第二个就是理论的接客过程了,所以不论是讲哪个框架的源码都是这样来的,mybatis 当然也是不例外的
- 初始化过程
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(“configuration.xml”));
就是咱们 mybatis 的外围在 SqlSessionFactory,首先 SqlSessionFactory build 进去 这个过程就会波及到解析各种配置文件,第一个要解析的就是 configuration 而后他的外面有很多的标签,你比如说 properties 等节点,而后外面有一个 mapper 节点,就是能够找到咱们的 mapper.xml 而后又去解析外面的节点,报告各种 cach,select 等等,之后把解析好之后 xml 通过命名空间和咱们的 mapper 接口绑定,并生成代码对象,把他放到 konwsmapper 这个 map 容器外面。最初就能够生成这个 SqlSessionFactory
- 真正的执行过程
就是当咱们的 mybatis 筹备好之后呢?咱们拿到这个 sqlsession 对象之后,如果是不要 spring 集成的话,那么接下来当然是要去获取咱们的 mapper 对象了 sqlsession.getMapper,当然这个获取的也是代理对象拉,而后到 MapperMethod,而后 SqlSession 将查询方法转发给 Executor。Executor 基于 JDBC 拜访数据库获取数据。Executor 通过反射将数据转换成 POJO 并返回给 SqlSession。将数据返回给调用者。
完结
接下来咱们看看 SpringBoot 和 SpringCloud 的组件哈,货色还很多,大家一起加油
日常求赞
好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是 真粉。
创作不易,各位的反对和认可,就是我创作的最大能源,咱们下篇文章见
微信 搜 “ 六脉神剑的程序人生 ” 回复 888 有我找的许多的材料送给大家