前言
文本已收录至我的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 有我找的许多的材料送给大家