【Java 核心知识体系】(3)

目录

8.字节增强

8.1JPDA

8.1.1概念

8.1.2原理

8.1.3实现

8.2 热替换

8.2.1概念

8.2.2原理

8.2.3实现

9.总结


8.字节增强

我们从类加载的应用介绍了热部署类隔离两大应用场景,但是基于类加载器的技术始终只是独立于JVM内核功能而存在的,也就是所有实现都只是基于最基础的类加载机制,并无应用其他JVM 高级特性,本章节我们开始从字节增强的层面介绍JVM的一些高级特性。

说到字节增强我们最先想到的是字节码,也就是本文最开头所要研究的class文件,任何合法的源码编译成class后被类加载器加载进JVM的方法区,也就是以字节码的形态存活在JVM的内存空间。这也就是我们为什么先有讲明白类的结构和加载过程,而字节码增强技术不只是在内存里面对class的字节码进行操纵,更为复杂的是class联动的上下游对象生命周期的管理

首先我们回忆一下我们开发过程中最为熟悉的一个场景就是本地debug调试代码。可能很多同学都已经习惯在IDE上对某句代码打上断点,然后逐步往下追踪代码执行的步骤。我们进一步想想,这个是怎么实现的,是一股什么样的力量能把已经跑起来的线程踩下刹车,一步一步往前挪?

我们知道线程运行其实就是在JVM的栈空间上不断的把代码对应的JVM指令集不断的送到CPU执行。那能阻止这个流程的力量也肯定是发生在JVM范围内,所以我们可以很轻松的预测到这肯定是JVM提供的机制,而不是IDE真的有这样的能力,只不过是JVM把这种能力封装成接口暴露出去,然后提供给IDE调用,而IDE只不过是通过界面交互来调用这些接口而已。那么下面我们就来介绍JVM这种重要的能力。

8.1JPDA

上面所讲的JVM提供的程序运行断点能力,其实JVM提供的一个工具箱 JVMTI(JVM TOOL Interface) 提供的接口,而这个工具箱是一套叫做 JPDA的架构定义的,本节我们就来聊聊JPDA。

JPDA(Java Platform Debugger Architecture) Java平台调试架构,既不是一个应用程序,也不是调试工具,而是定义了一系列设计良好的接口和协议用于调试java代码,我们将会从三个层面来讲解JPDA。

8.1.1概念

  • JVMTI

    JVMTI (Java Virtual Machine Tool Interface)Java 虚拟机调试接口,处于最底层,是我们上文所提到的JVM开放的能力,JPDA 规定了JDK 必须提供一个叫做JVMTI(Java6之前是由JVMPI和JVMDI组成,Java6开始废弃掉统一为JVMTI)的工具箱,也就是定义了一系列接口能力,比如获取栈帧、设置断点、断点响应等接口,具体开放的能力参考JVMDI官方API文档。

  • JDWP

    JDWP (Java Debug Wire Protocol) Java 调试连线协议,存在在中间层,定义信息格式,定义调试者和被调试程序之间请求的协议转换,位于JDI下一层,JDI更为抽象,JDWP则关注实现。也就是说JVM定义好提供的能力,但是如何调用JVM提供的接口也是需要规范的,就比如我们Servlet容器也接收正确合法的HTTP请求就可以成功调用接口。JPDA同样也规范了调用JVMTI接口需要传入数据的规范,也就是请求包的格式,类似HTTP的数据包格式。但是JPDA并不关心请求来源,也就是说只要调用JVMTI的请求方式和数据格式对了就可以,不论是来做远程调用还是本地调用。JDWP制定了调试者和被调试应用的字节流动机制,但没有限定具体实现,可以是远程的socket连接,或者本机的共享内存,当然还有自定义实现的通信协议。既然只是规范了调用协议,并不局限请求来源,而且也没限制语言限制,所以非java语言只要发起调用符合规范就可以,这个大大丰富了异构应用场景,具体的协议细节可以参考JDWP官方规范文档。

  • JDI

    JDI(Java Debug Interface)Java调试接口处在最上层,基于Java开发的调试接口,也就是我们调试客户端,客户端代码封装在 jdk下面tools.jar的com.sun.jdi包里面,java 程序可以直接调用的接口集合,具体提供的功能可以参考JDI官方API文档。

8.1.2原理

介绍完JPDA的架构体系后,我们了解到JAVA调试平台各个层级的作用,这一节我们更近一步讲解JPDA各个层面的工作原理,以及三个层级结合起来时如何交互的。

JVMTI

我们JVMTI 是JVM提供的一套本地接口,包含了非常丰富的功能,我们调试和优化代码需要操作JVM,多数情况下就是调用到JVMTI,从官网我们可以看到,JVMTI包含了对JVM线程/内存/堆/栈/类/方法/变量/事件/定时器处理等的20多项功能。但其实我们通常不是直接调用JVMTI,而是创建一个代理客户端,我们可以自由的定义对JVMTI的操作然后打包到代理客户端里面如libagent.so。

当目标程序执行时会启动JVM,这个时候在目标程序运行前会加载代理客户端,所以代理客户端是跟目标程序运行在同一个进程上。这样一来外部请求就通过代理客户端间接调用到JVMTI,这样的好处是我们可以在客户端Agent里面定制高级功能,而且代理客户端编译打包成一个动态链接库之后可以复用,提高效率。我们简单描述一下代理客户端Agent的工作流程。

建立代理客户端首先需要定义Agent的入口函数,犹如Java类的main方法一样:

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved);

然后JVM在启动的时候就会把JVMTI的指针JavaVM传给代理的入口函数,options则是传参,有了这个指针后代理就可以充分调用JVMTI的函数了。

//设置断点,参数是调试目标方法和行数位置
jvmtiError SetBreakpoint(jvmtiEnv* env,jmethodID method,jlocation location);
//当目标程序执行到指定断点,目标线程则被挂起
jvmtiError SuspendThread(jvmtiEnv* env,jthread thread);

当然除了JVM启动时可以加载代理,运行过程中也是可以的,这个下文我们讲字节码增强还会再说到。

JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* vm, char *options, void *reserved);

有兴趣的同学可以自己动手写一个Agent试试,通过调用JVMTI接口可以实现自己定制化的调试工具。

JDWP

上文我们知道调用JVMTI需要建立一个代理客户端,但是假如我建立了包含通用功能的Agent想开发出去给所有调试器使用,有一种方式是资深开发者通过阅读我的文档后进行开发调用,还有另外一种方式就是我在我的Agent里面加入了JDWP协议模块,这样调试器就可以不用关心我的接口细节,只需按照阅读的协议发起请求即可。JDWP是调试器和JVM中间的协议规范,类似HTTP协议一样,JDWP也定义规范了握手协议和报文格式。

调试器发起请求的握手流程:

1)调试器发送一段包含“JDWP-Handshake”的14个bytes的字符串

2)JVM回复同样的内容“JDWP-Handshake”

完成握手流程后就可以像HTTP一样向JVM的代理客户端发送请求数据,同时回复所需参数。请求和回复的数据帧也有严格的结构,请求的数据格式为Command Packet,回复的格式为Reply Packet,包含包头和数据两部分,具体格式参考官网。

实际上JDWP却是也是通过建立代理客户端来实现报文格式的规范,也就是JDWP Agent 里面的JDWPTI实现了JDWP对协议的定义。JDWP的功能是由JDWP传输接口(Java Debug Wire Protocol Transport Interface)实现的,具体流程其实跟JVMTI差不多,也是讲JDWPTI编译打包成代理库后,在JVM启动的时候加载到目标进程。那么调试器调用的过程就是JDWP Agent接收到请求后,调用JVMTI Agent,JDWP负责定义好报文数据,而JDWPTI则是具体的执行命令和响应事件。

JDI

前面已经解释了JVMTI和JDWP的工作原理和交互机制,剩下的就是搞清楚面向用户的JDI是如何运行的。首先JDI位于JPDA的最顶层入口,它的实现是通过JAVA语言编写的,所以可以理解为Java调试客户端对JDI接口的封装调用,比如我们熟悉的IDE界面启动调试,或者JAVA的命令行调试客户端JDB。

通常我们设置好目标程序的断点之后启动程序,然后通过调试器启动程序之前,调试器会先获取JVM管理器,然后通过JVM管理器对象virtualMachineManager获取连接器Connector,调试器与虚拟机获得链接后就可以启动目标程序了。如下代码:

VirtualMachineManager virtualMachineManager = Bootstrap.virtualMachineManager();

JDI完成调试需要实现的功能有三个模块:数据、链接、事件

  • 数据

    调试器要调试的程序在目标JVM上,那么调试之前肯定需要将目标程序的执行环境同步过来,不然我们压根就不知道要调试什么,所以需要一种镜像机制,把目标程序的堆栈方法区包含的数据以及接收到的事件请求都映射到调试器上面。那么JDI的底层接口Mirror就是干这样的事,具体数据结构可以查询文档。

  • 链接

    我们知道调试器跟目标JVM直接的通讯是双向的,所以链接双方都可以发起。一个调试器可以链接多个目标JVM,但是一个目标虚拟机只能提供给一个调试器,不然就乱套了不知道听谁指令了。JDI定义三种链接器:启动链接器(LaunchingConnector)、依附链接器(AttachingConnector)、监听链接器(ListeningConnector)和。分别对应的场景是目标程序JVM启动时发起链接、调试器中途请求接入目标程序JVM和调试器监听到被调试程序返回请求时发起的链接。

  • 事件

    也就是调试过程中对目标JVM返回请求的响应。

讲解完JPDA体系的实现原理,我们再次梳理一下调试的整个流程:

调试器 —> JDI客户端 —> JDWP Agent—> JVMTI Agent —>> JVMTI —> Application

8.1.3实现

现在我们已经对整个JPDA结构有了深入理解,接下来我们就通过对这些朴素的原理来实现程序的断点调试。当然我们不会在这里介绍从IDE的UI断点调试的过程,因为对这套是使用已经非常熟悉了,我们知道IDE的UI断点调试本质上是调试器客户端对JDI的调用,那我们就通过一个调试的案例来解释一下这背后的原理。

搭建服务

首先我们需要先搭建一个可供调试的web服务,这里我首选springboot+来搭建,通过官网生成样例project或者maven插件都可以,具体的太基础的就不在这里演示,该服务只提供一个Controller包含的一个简单方法。如果使用Tomcat部署,则可以通过自有的开关catalina jpda start来启动debug模式。

package com.zooncool.debug.rest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController("/debug")
public class DebugController {
    @GetMapping
    public String ask(@RequestParam("name") String name) {
        String message = "are you ok?" + name;
        return message;
    }
}

启动服务

搭建好服务之后我们先启动服务,我们通过maven来启动服务,其中涉及到的一些参数下面解释。

mvn spring-boot:run -Drun.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001"
或者
mvn spring-boot:run -Drun.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8001"
  • mvn:maven的脚本命令这个不用解释

  • Spring-boot:run:启动springboot工程

  • -Drun.jvmArguments:执行jvm环境的参数,里面的参数值才是关键

  • -Xdebug

    Xdebug开启调试模式,为非标准参数,也就是可能在其他JVM上面是不可用的,Java5之后提供了标准的执行参数agentlib,下面两种参数同样可以开启debug模式,但是在JIT方面有所差异,这里先不展开。

    java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8001

    java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8001

  • Xrunjdwp/jdwp=transport:表示连接模式是本地内存共享还是远程socket连接

  • server:y表示打开socket监听调试器的请求;n表示被调试程序像客户端一样主动连接调试器

  • suspend:y表示被调试程序需要等到调试器的连接请求之后才能启动运行,在此之前都是挂起的,n表示被调试程序无需等待直接运行。

  • address:被调试程序启动debug模式后监听请求的地址和端口,地址缺省为本地。

执行完上述命令后,就等着我们调试器的请求接入到目标程序了。

调试接入

我们知道java的调试器客户端为jdb,下面我们就使用jdb来接入我们的目标程序。

#jdb 通过attach参数选择本地目标程序,同时附上目标程序的源码,回想之前我们讲到的JDI的镜像接口,就是把目标程序的堆栈结构同步过来,如果能我们提供的源码对应上,那就可以在源码上面显示断点标志
$ jdb -attach localhost:8001 -sourcepath /Users/linzhenhua/Documents/repositories/practice/stackify-master/remote-debugging/src/main/java/
设置未捕获的java.lang.Throwable
设置延迟的未捕获的java.lang.Throwable
正在初始化jdb...

#stop,选择对应方法设置断点
> stop in com.zooncool.debug.rest.DebugController.ask(java.lang.String)
设置断点com.zooncool.debug.rest.DebugController.ask(java.lang.String)

#如果我们设置不存在的方法为断点,则会有错误提示
> stop in com.zooncool.debug.rest.DebugController.ask2(java.lang.String)
无法设置断点com.zooncool.debug.rest.DebugController.ask2(java.lang.String): com.zooncool.debug.rest.DebugController中没有方法ask2

#这时候我们已经设置完断点,就可以发起个HTTP请求
#http://localhost:7001/remote-debugging/debug/ask?name=Jack
#发起请求后我们回到jdb控制台,观察是否命中断点
> 断点命中: "线程=http-nio-7001-exec-5", com.zooncool.debug.rest.DebugController.ask(), 行=14 bci=0
14            String message = "are you ok?" + name;

#list,对照源码,确实是进入ask方法第一行命中断点,也就是14行,这时候我们可以查看源码
http-nio-7001-exec-5[1] list
10    @RestController("/debug")
11    public class DebugController {
12        @GetMapping
13        public String ask(@RequestParam("name") String name) {
14 =>         String message = "are you ok?" + name;
15            return message;
16        }
17    }

#locals,观察完源码,我们想获取name的传参,跟URL传入的一致
http-nio-7001-exec-5[1] locals
方法参数:
name = "Jack"
本地变量:

#print name,打印入参
http-nio-7001-exec-5[1] print name
 name = "Jack"

#where,查询方法调用的栈帧,从web容器入口调用方法到目标方法的调用链路
http-nio-7001-exec-5[1] where
  [1] com.zooncool.debug.rest.DebugController.ask (DebugController.java:14)
  ...
  [55] java.lang.Thread.run (Thread.java:748)
#step,下一步到下一行代码
http-nio-7001-exec-5[1] step
> 已完成的步骤: "线程=http-nio-7001-exec-5", com.zooncool.debug.rest.DebugController.ask(), 行=15 bci=20
15            return message;

#step up,完成当前方法的调用
http-nio-7001-exec-5[1] step up
> 已完成的步骤: "线程=http-nio-7001-exec-5", sun.reflect.NativeMethodAccessorImpl.invoke(), 行=62 bci=103

#cont,结束调试,执行完毕
http-nio-7001-exec-5[1] cont
> 

#clear,完成调试任务,清除断点
> clear
断点集:
        断点com.zooncool.debug.rest.DebugController.ask(java.lang.String)
        断点com.zooncool.debug.rest.DebugController.ask2(java.lang.String)
#选择一个断点删除
> clear com.zooncool.debug.rest.DebugController.ask(java.lang.String)
已删除: 断点com.zooncool.debug.rest.DebugController.ask(java.lang.String)

我们已经完成了命令行调试的全部流程,stop/list/locals/print name/where/step/step up/cont/clear这些命令其实就是IDE的UI后台调用的脚本。而这些脚本就是基于JDI层面的接口所提供的能力,下面我们还有重点观察一个核心功能,先从头再设置一下断点。

#stop,选择对应方法设置断点
> stop in com.zooncool.debug.rest.DebugController.ask(java.lang.String)
设置断点com.zooncool.debug.rest.DebugController.ask(java.lang.String)
#这时候我们已经设置完断点,就可以发起个HTTP请求
#http://localhost:7001/remote-debugging/debug/ask?name=Jack
#发起请求后我们回到jdb控制台,观察是否命中断点
> 断点命中: "线程=http-nio-7001-exec-5", com.zooncool.debug.rest.DebugController.ask(), 行=14 bci=0
14            String message = "are you ok?" + name;
#print name,打印入参
http-nio-7001-exec-5[1] print name
 name = "Jack"
#如果这个时候我们想替换掉Jack,换成Lucy
http-nio-7001-exec-6[1] set name = "Lucy"   
 name = "Lucy" = "Lucy"
#进入下一步
http-nio-7001-exec-6[1] step
> 已完成的步骤: "线程=http-nio-7001-exec-6", com.zooncool.debug.rest.DebugController.ask(), 行=15 bci=20
15            return message;
#查看变量,我们发现name的值已经被修改了
http-nio-7001-exec-6[1] locals
方法参数:
name = "Lucy"
本地变量:
message = "are you ok?Lucy"

至此我们已经完成了JPDA的原理解析到调试实践,也理解了JAVA调试的工作机制,其中留下一个重要的彩蛋就是通过JPDA进入调试模式,我们可以动态的修改JVM内存对象和类的内容,这也讲引出下文我们要介绍的字节码增强技术。

8.2 热替换

8.2.1概念

终于来到热替换这节了,前文我们做了好多铺垫,介绍热替换之前我们稍稍回顾一下热部署。我们知道热部署是“独立”于JVM之外的一门对类加载器应用的技术,通常是应用容器借助自定义类加载器的迭代,无需重启JVM却能更新代码从而达到热部署,也就是说热部署是JVM之外容器提供的一种能力。而本节我们介绍的热替换技术是实打实JVM提供的能力,是JVM提供的一种能够实时更新内存类结构的一种能力,这种实时更新JVM方法区类结构的能力当然也是无需重启JVM实例。

热替换HotSwap是Sun公司在Java 1.4版本引入的一种新实验性技术,也就是上一节我们介绍JPDA提到的调试模式下可以动态替换类结构的彩蛋,这个功能被集成到JPDA框架的接口集合里面,首先我们定义好热替换的概念。

  • 热替换(HotSwap):使用字节码增强技术替换JVM内存里面类的结构,包括对应类的对象,而不需要重启虚拟机。

8.2.2原理

前文从宏观上介绍了JVM实例的内存布局和垃圾回收机制,微观上也解释了类的结构和类加载机制,上一节又学习了JAVA的调试框架,基本上我们对JVM的核心模块都已经摸透了,剩下的就是攻克字节码增强的技术了。而之前讲的字节码增强技术也仅仅是放在JPDA里面作为实验性技术,而且仅仅局限在方法体和变量的修改,无法动态修改方法签名或者增删方法,因为字节码增强涉及到垃圾回收机制,类结构变更,对象引用,即时编译等复杂问题。在HotSwap被引进后至今,JCP也未能通过正式的字节码增强实现。

JAVA是一门静态语言,而字节码增强所要达的效果就是让Java像动态语言一样跑起来,无需重启服务器。下面我们介绍字节码增强的基本原理。

  • 反射代理

    反射代理不能直接修改内存方法区的字节码,但是可以抽象出一层代理,通过内存新增实例来实现类的更新

  • 原生接口

    jdk上层提供面向java语言的字节码增强接口java.lang.instrument,通过实现ClassFileTransformer接口来操作JVM方法区的类文件字节码。

  • JVMTI代理

    JVM的JVMTI接口包含了操作方法区类文件字节码的函数,通过创建代理,将JVMTI的指针JavaVM传给代理,从而拥有JVM 本地操作字节码的方法引用。

  • 类加载器织入

    字节码增强接口加上类加载器的织入,结合起来也是一种热替换技术。

  • JVM增强

    直接新增JVM分支,增加字节码增强功能。

8.2.3实现

但是尽管字节码增强是一门复杂的技术,这并不妨碍我们进一步的探索,下面我们介绍几种常见的实现方案。

  • Instrumentation

  • AspectJ

  • ASM

  • DCEVM

  • JREBEL

  • CGLIB

  • javassist

  • BCEL

具体的我会挑两个具有代表性的工具深入讲解,篇幅所限,这里就不展开了。

9.总结

JVM是程序发展至今的一颗隗宝,是程序设计和工程实现的完美结合。JVM作为作为三大工业级程序语言为首JAVA的根基,本文试图在瀚如烟海的JVM海洋中找出其中最耀眼的冰山,并力求用简洁的逻辑线索把各个冰山串起来,在脑海中对JVM的观感有更加立体的认识。更近一步的认识JVM对程序设计的功力提示大有裨益,而本文也只是将海平面上的冰山链接起来,但这只是冰山一角,JVM更多的底层设计和实现细节还远远没有涉及到,而且也不乏知识盲区而没有提及到的,路漫漫其修远兮,JVM本身也在不断的推陈出新,借此机会总结出JVM的核心体系,以此回顾对JVM知识的查漏补缺,也是一次JVM的认知升级。最后还是例牌来两张图结束JVM的介绍,希望对更的同学有帮助。

参考

 公众号:编程原理林振华 编程原理

1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ....................................................................................................................................................... 19 2.1. 线程 ...................................................................................................................................................... 20 2.2. JVM 内存区域 ..................................................................................................................................... 21 2.2.1. 程序计数器(线程私有) ................................................................................................................ 22 2.2.2. 虚拟机栈(线程私有) .................................................................................................................... 22 2.2.3. 本地方法区(线程私有) ................................................................................................................ 23 2.2.4. 堆(Heap-线程共享)-运行时数据区 ...................................................................................... 23 2.2.5. 方法区/永久代(线程共享) ..................................................................................................... 23 2.3. JVM 运行时内存 ................................................................................................................................. 24 2.3.1. 新生代 .......................................................................................................................................... 24 2.3.1.1. 2.3.1.2. 2.3.1.3. 2.3.1.4. Eden 区 .................................................................................................................................................... 24 ServivorFrom........................................................................................................................................... 24 ServivorTo .............................................................................................................................................. 24 MinorGC 的过程(复制->清空->互换) ....................................................................................... 24 1:eden、servicorFrom 复制到 ServicorTo,年龄+1................................................................................... 25 2:清空 eden、servicorFrom............................................................................................................................. 25 3:ServicorTo 和 ServicorFrom 互换................................................................................................................25 2.3.3.1. 2.4.1. 如何确定垃圾 .............................................................................................................................. 26 2.4.1.1. 引用计数法............................................................................................................................................... 26 2.4.1.2. 可达性分析............................................................................................................................................... 26 2.3.2. 2.3.3. 老年代 .......................................................................................................................................... 25 永久代 .......................................................................................................................................... 25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................................................................................................................. 26 2.4.2. 2.4.3. 2.4.4. 2.4.5. 2.4.5.1. 2.4.5.2. 2.6.1. 2.6.1.1. 2.6.1.2. 2.7.1. 2.7.2. 2.7.3. 2.7.4. 2.7.5. 2.7.6. 2.7.6.1. 标记清除算法(Mark-Sweep) .............................................................................................. 27 复制算法(copying)................................................................................................................. 27 标记整理算法(Mark-Compact).................................................................................................. 28 分代收集算法 .............................................................................................................................. 29 新生代与复制算法 .............................................................................................................................. 29 老年代与标记复制算法 ......................................................................................................................29 2.5. JAVA 四中引用类型 ........................................................................................................................... 30 2.5.1. 强引用 .......................................................................................................................................... 30 2.5.2. 软引用 .......................................................................................................................................... 30 2.5.3. 弱引用 .......................................................................................................................................... 30 2.5.4. 虚引用 .......................................................................................................................................... 30 2.6. GC 分代收集算法 VS 分区收集算法................................................................................................ 30 分代收集算法 .............................................................................................................................. 30 在新生代-复制算法............................................................................................................................. 30 在老年代-标记整理算法.....................................................................................................................30 分区收集算法 .............................................................................................................................. 31 2.7. GC 垃圾收集器 ................................................................................................................................... 31 2.6.2. Serial 垃圾收集器(单线程、复制算法)................................................................................ 31 ParNew 垃圾收集器(Serial+多线程) ................................................................................... 31 .......................................................... 32 ........................................................................... 32 ......................................................................... 33 ..................................................................................... 33 初始标记 .............................................................................................................................................. 33 Parallel Scavenge 收集器(多线程复制算法、高效) Serial Old 收集器(单线程标记整理算法 ) Parallel Old 收集器(多线程标记整理算法) CMS 收集器(多线程标记清除算法) 2.7.6.2. 2.7.6.3. 2.7.6.4. 2.8.1. 2.8.2. 2.8.3. 2.8.4. 2.8.5. 2.8.1. 2.8.2. 2.8.2.1. 2.8.2.2. 2.8.3. 2.8.4. 2.8.5. 并发标记 .............................................................................................................................................. 34 重新标记 .............................................................................................................................................. 34 并发清除 .............................................................................................................................................. 34 G1 收集器 .................................................................................................................................... 34 2.8. JAVA IO/NIO ....................................................................................................................................... 34 2.7.7. 2.9. 2.9.2. 2.9.2.1. 2.9.2.2. 2.9.2.3. 2.9.3. 2.9.4. 2.9.4.1. 2.9.4.2. 阻塞IO模型 ................................................................................................................................ 34 ............................................................................................................................ 35 ........................................................................................................................ 35 ........................................................................................................................ 36 ................................................................................................................................ 36 .................................................................................................................................. 36 .................................................................................................................................... 37 NIO 的缓冲区 .....................................................................................................................................38 NIO 的非阻塞 .....................................................................................................................................38 ....................................................................................................................................... 40 非阻塞 IO 模型 多路复用 IO 模型 信号驱动 IO 模型 ............................................................................................................................................ 40 ........................................................................................................................................ 40 JVM 类加载机制 ................................................................................................................................. 41 2.9.1.1. 2.9.1.2. 2.9.1.3. 2.9.1.4. 2.9.1.5. 2.9.1.6. 2.9.1.7. 2.9.1.8. 加载 .......................................................................................................................................................... 41 验证 .......................................................................................................................................................... 41 准备 .......................................................................................................................................................... 41 解析 .......................................................................................................................................................... 41 符号引用 .............................................................................................................................................. 42 直接引用 .............................................................................................................................................. 42 初始化 ...................................................................................................................................................... 42 类构造器 .............................................................................................................................. 42 类加载器 ...................................................................................................................................... 42 启动类加载器(Bootstrap ClassLoader) ......................................................................................... 43 扩展类加载器(Extension ClassLoader)..........................................................................................43 应用程序类加载器(Application ClassLoader): ..........................................................................43 双亲委派 ...................................................................................................................................... 43 OSGI(动态模型系统) ............................................................................................................ 44 动态改变构造 ...................................................................................................................................... 44 模块化编程与热插拔 .......................................................................................................................... 44 3. JAVA集合............................................................................................................................................45 3.1. 接口继承关系和实现 .......................................................................................................................... 45 3.2. LIST ....................................................................................................................................................... 47 3.2.1. ArrayList(数组)....................................................................................................................... 47 3.2.2. Vector(数组实现、线程同步) ............................................................................................... 47 3.2.3. LinkList(链表) ......................................................................................................................... 47 3.3. SET ....................................................................................................................................................... 48 3.3.1.1. 3.3.1.2. HashSet(Hash 表) ............................................................................................................................. 48 TreeSet(二叉树) ................................................................................................................................ 49 LinkHashSet(HashSet+LinkedHashMap) ................................................................................... 49 3.3.1.3. 3.4. MAP....................................................................................................................................................... 50 3.4.1. HashMap(数组+链表+红黑树)............................................................................................. 50 3.4.1.1. JAVA7 实现 ............................................................................................................................................. 50 3.4.1.2. JAVA8 实现 ............................................................................................................................................. 51 3.4.2. ConcurrentHashMap.................................................................................................................. 51 3.4.2.1. 3.4.2.2. 3.4.2.3. 3.4.2.4. Segment 段.............................................................................................................................................. 51 线程安全(Segment 继承 ReentrantLock 加锁) .............................................................................. 51 并行度(默认 16) ................................................................................................................................. 52 Java8 实现 (引入了红黑树) .............................................................................................................. 52 13/04/2018 Page 2 of 283 异步IO模型 JAVA IO 包 JAVA NIO Channel Buffer Selector 3.4.3. HashTable(线程安全) ........................................................................................................... 53 3.4.4. TreeMap(可排序) .................................................................................................................. 53 3.4.5. LinkHashMap(记录插入顺序) .............................................................................................. 53 4. JAVA 多线程并发.................................................................................................................................54 4.1.1. JAVA 并发知识库 ....................................................................................................................... 54 4.1.2. JAVA 线程实现/创建方式 .......................................................................................................... 54 4.1.2.1. 4.1.2.2. 4.1.2.3. 4.1.2.4. 继承 Thread 类 ........................................................................................................................................ 54 实现 Runnable 接口。............................................................................................................................ 54 ExecutorService、Callable、Future 有返回值线程.............................................................55 基于线程池的方式................................................................................................................................... 56 4.1.3. 4 种线程池 ................................................................................................................................... 56 4.1.3.1. 4.1.3.2. 4.1.3.3. newSingleThreadExecutor ................................................................................................................. 58 4.1.4. 线程生命周期(状态) .................................................................................................................... 58 4.1.3.4. 4.1.4.1. 4.1.4.2. 4.1.4.3. 4.1.4.4. 新建状态(NEW) ................................................................................................................................. 58 就绪状态(RUNNABLE): ................................................................................................................. 59 运行状态(RUNNING): .................................................................................................................... 59 阻塞状态(BLOCKED):....................................................................................................................59 4.1.9.5. 4.1.9.6. 4.1.9.7. 13/04/2018 Semaphore 信号量 ................................................................................................................................. 68 ................................................................................................................................. 68 ................................................................................................................................................................ 68 ........................................................................................................................... 69 AtomicInteger .......................................................................................................................................... 69 Page 3 of 283 newCachedThreadPool ......................................................................................................................... 57 ............................................................................................................................. 57 newScheduledThreadPool .................................................................................................................... 58 newFixedThreadPool 等待阻塞(o.wait->等待对列): ...................................................................................................................... 59 .......................................................................................................................................... 59 ............................................................................................................................................ 59 线程死亡(DEAD)................................................................................................................................ 59 ............................................................................................................................................................... 59 ............................................................................................................................................................... 59 ............................................................................................................................................................... 59 4.1.5. 终止线程 4 种方式 ...................................................................................................................... 60 同步阻塞(lock->锁池) 其他阻塞(sleep/join) 4.1.4.5. 4.1.5.1. 4.1.5.2. 4.1.5.3. 4.1.5.4. 正常运行结束........................................................................................................................................... 60 使用退出标志退出线程...........................................................................................................................60 Interrupt 方法结束线程 ........................................................................................................................... 60 stop 方法终止线程(线程不安全)....................................................................................................... 61 正常结束. 异常结束. 调用 stop 4.1.6. sleep 与 wait 区别....................................................................................................................... 61 4.1.7. start 与 run 区别 .......................................................................................................................... 62 4.1.8. JAVA 后台线程 ........................................................................................................................... 62 4.1.9. JAVA 锁 ....................................................................................................................................... 63 4.1.9.1. 4.1.9.2. 4.1.9.3. 乐观锁 ...................................................................................................................................................... 63 悲观锁 ...................................................................................................................................................... 63 自旋锁 ...................................................................................................................................................... 63 自旋锁的优缺点....................................................................................................................................................63 自旋锁时间阈值(1.6 引入了适应性自旋锁) .................................................................................................. 63 自旋锁的开启........................................................................................................................................................ 64 4.1.9.4. Synchronized 同步锁.............................................................................................................................. 64 ....................................................................................................................................... 64 ....................................................................................................................................... 64 Synchronized 作用范围 Synchronized 核心组件 Synchronized 实现 ............................................................................................................................................... 64 ReentrantLock......................................................................................................................................... 66 ........................................................................................................................................... 66 ................................................................................................................................................................ 66 .................................................................................................................................................................... 67 ........................................................................................................................ 67 ............................................................................................................................................. 67 ......................................................................................................... 68 tryLock 和 lock 和 lockInterruptibly 的区别........................................................................................................ 68 Lock 接口的主要方法 非公平锁 公平锁 ReentrantLock 与 synchronized ReentrantLock 实现 Condition 类和 Object 类锁方法区别区别 实现互斥锁(计数器为 1) 代码实现 Semaphore 与 ReentrantLock 4.1.9.8. 4.1.9.9. 4.1.9.10. 4.1.9.11. 4.1.9.12. 4.1.9.14. 4.1.9.15. 4.1.9.16. 可重入锁(递归锁)............................................................................................................................... 69 公平锁与非公平锁................................................................................................................................... 70 ..................................................................................................................................................... 70 ........................................................................................................................................... 70 ReadWriteLock 读写锁......................................................................................................................70 ........................................................................................................................................................................ 70 ........................................................................................................................................................................ 70 公平锁(Fair) 非公平锁(Nonfair) 读锁 写锁 共享锁和独占锁 .................................................................................................................................. 70 .................................................................................................................................................................... 70 .................................................................................................................................................................... 70 重量级锁(Mutex Lock)................................................................................................................71 轻量级锁 .............................................................................................................................................. 71 锁升级.................................................................................................................................................................... 71 独占锁 共享锁 4.1.9.13. 偏向锁 .................................................................................................................................................. 71 分段锁 .................................................................................................................................................. 71 锁优化 .................................................................................................................................................. 71 减少锁持有时间 .................................................................................................................................................... 72 ............................................................................................................................................................ 72 .................................................................................................................................................................... 72 .................................................................................................................................................................... 72 .................................................................................................................................................................... 72 4.1.10. 线程基本方法..............................................................................................................................72 减小锁粒度 锁分离 锁粗化 锁消除 4.1.10.1. 4.1.10.2. 4.1.10.3. 4.1.10.4. 4.1.10.5. 4.1.10.6. 4.1.10.7. 4.1.10.8. 线程等待(wait) ............................................................................................................................... 73 线程睡眠(sleep)............................................................................................................................. 73 线程让步(yield) .............................................................................................................................. 73 线程中断(interrupt)........................................................................................................................ 73 Join 等待其他线程终止 ...................................................................................................................... 74 为什么要用 join()方法? .................................................................................................................... 74 线程唤醒(notify)............................................................................................................................. 74 其他方法: .......................................................................................................................................... 74 4.1.11. 线程上下文切换..........................................................................................................................75 4.1.11.1. 4.1.11.2. 4.1.11.3. 4.1.11.4. 4.1.11.5. 4.1.11.6. 4.1.11.7. 进程......................................................................................................................................................75 上下文..................................................................................................................................................75 寄存器..................................................................................................................................................75 程序计数器 .......................................................................................................................................... 75 PCB-“切换桢”................................................................................................................................. 75 上下文切换的活动: .......................................................................................................................... 76 引起线程上下文切换的原因 .............................................................................................................. 76 4.1.12. 同步锁与死锁..............................................................................................................................76 4.1.12.1. 同步锁 .................................................................................................................................................. 76 4.1.12.2. 死锁 ...................................................................................................................................................... 76 4.1.13. 线程池原理..................................................................................................................................76 4.1.14.1. 4.1.14.2. 4.1.14.3. 4.1.14.4. 4.1.14.5. 4.1.14.6. 4.1.14.7. 4.1.14.8. 4.1.13.1. 4.1.13.2. 4.1.13.3. 4.1.13.4. 线程复用 .............................................................................................................................................. 76 ...................................................................................................................................... 76 .............................................................................................................................................. 78 ......................................................................................................................... 78 4.1.14. JAVA 阻塞队列原理.................................................................................................................... 79 线程池的组成 拒绝策略 Java 线程池工作过程 阻塞队列的主要方法 .......................................................................................................................... 80 ............................................................................................................................................................ 80 .................................................................................................................................................... 81 ............................................................................................................................. 81 ....................................................................................... 82 ......................................................................... 82 .............................................................. 82 .......................................................................................... 82 .............................................................. 83 ...................................................................................................................... 83 插入操作: 获取数据操作: Java 中的阻塞队列 ArrayBlockingQueue(公平、非公平) LinkedBlockingQueue(两个独立锁提高并发) PriorityBlockingQueue(compareTo 排序实现优先) DelayQueue(缓存失效、定时任务 ) SynchronousQueue(不存储数据、可用于传递数据) LinkedTransferQueue 13/04/2018 Page 4 of 283 4.1.14.9. LinkedBlockingDeque ..................................................................................................................... 83 4.1.15. CyclicBarrier、CountDownLatch、Semaphore 的用法 ........................................................ 84 4.1.15.1. 4.1.15.2. 4.1.15.3. ................................................................................................ 84 ............................................... 84 ....................................................................... 85 CountDownLatch(线程计数器 ) CyclicBarrier(回环栅栏-等待至 barrier 状态再全部同时执行) Semaphore(信号量-控制同时访问的线程个数) 4.1.16. volatile 关键字的作用(变量可见性、禁止重排序) ............................................................. 87 变量可见性............................................................................................................................................................ 87 禁止重排序............................................................................................................................................................ 87 ..................................................................................................................... 87 ................................................................................................................................................................ 87 4.1.17. 如何在两个线程之间共享数据...................................................................................................88 将数据抽象成一个类,并将数据的操作作为这个类的方法.............................................................................88 .................................................................................................................. 89 4.1.18. ThreadLocal 作用( )........................................................................................ 90 .............................................................................................................. 90 ................................................................................................................................................................ 91 4.1.19. synchronized 和 ReentrantLock 的区别 .................................................................................. 91 4.1.19.1. .................................................................................................................................. 91 4.1.19.2. .................................................................................................................................. 92 4.1.20. ConcurrentHashMap 并发......................................................................................................... 92 4.1.20.1. .......................................................................................................................................... 92 4.1.20.2. .......................................................................................................... 92 ................................................. 93 4.1.21. Java 中用到的线程调度 ............................................................................................................. 93 比 sychronized 更轻量级的同步锁 适用场景 Runnable 对象作为一个类的内部类 ThreadLocalMap(线程的一个属性) 线程本地存储 使用场景 两者的共同点: 两者的不同点: 4.1.21.1. 4.1.21.2. 4.1.21.3. 4.1.21.4. 减小锁粒度 ...................................................................................................................................... 93 ...................................................................................................................................... 93 ............................................................................................. 94 ..................................................................................................................... 94 4.1.22. 进程调度算法..............................................................................................................................94 4.1.22.1. 4.1.22.2. 4.1.22.3. ...................................................................................................................................... 94 ...................................................................................................................... 95 .............................................................................................................. 96 )..................................................................96 .......................................................................................................................................... 96 ........................................................................... 97 ............................................................................................................................................. 98 4.1.24. 什么是AQS(抽象的队列同步器).........................................................................................98 Exclusive 独占资源-ReentrantLock ................................................................................................................... 99 Share 共享资源-Semaphore/CountDownLatch ............................................................................................... 99 同步器的实现是 ABS 核心(state 资源状态计数) ....................................................................................... 100 ReentrantReadWriteLock 实现独占和共享两种方式.....................................................................................100 5. JAVA基础..........................................................................................................................................101 4.1.23. 什么是CAS( 4.1.23.1. 4.1.23.2. 4.1.23.3. 5.1.1. 5.1.1.1. 5.1.1.2. 5.1.1.3. 5.1.1.4. JAVA 异常分类及处理.............................................................................................................. 101 .................................................................................................................................................... 101 ............................................................................................................................................ 101 ..................................................................................................................................................................... 101 ........................................................................... 101 ................................................................................................................................ 102 ......................................................... 102 .................................................................................................................. 102 ............................................................................................................ 102 13/04/2018 Page 5 of 283 ConcurrentHashMap 分段锁 ConcurrentHashMap 是由 Segment 数组结构和 HashEntry 数组结构组成 抢占式调度: 协同式调度: JVM 的线程调度实现(抢占式调度) 线程让出 cpu 的情况: 优先调度算法 高优先权优先调度算法 基于时间片的轮转调度算法 比较并交换-乐观锁机制-锁自旋 概念及特性 原子包 java.util.concurrent.atomic(锁自旋) ABA 问题 概念 异常分类 Error Exception(RuntimeException、CheckedException) 异常的处理方式 遇到问题不进行具体处理,而是继续抛给调用者 (throw,throws) try catch 捕获异常针对性处理方式 Throw 和 throws 的区别: 位置不同 功能不同: 5.1.2. 5.1.2.1. 5.1.2.2. 5.1.2.3. 5.1.2.4. 5.1.2.5. 5.1.2.6. 5.1.2.7. 5.1.3. 5.1.4.1. 5.1.4.2. 5.1.4.3. 5.1.4.4. @Documented 描述-javadoc @Inherited 阐述了某个被标注的类型是被继承的 5.1.5.1. 5.1.5.2. 5.1.5.3. 5.1.5.4. 泛型方法() ............................................................................................................................. 112 泛型类 ............................................................................................................................................. 112 类型通配符? .......................................................................................................................................... 113 类型擦除 ................................................................................................................................................ 113 .............................................................................................................................................................. 102 .......................................................................................................................................................... 102 JAVA 反射 ................................................................................................................................. 103 ............................................................................................................................................ 103 ............................................................ 103 ................................................................................................................................ 103 .................................................................................................................................. 103 ...................................................................................................................... 104 .................................................................................................................................... 104 ............................................................................ 104 ..................................................................... 104 ............................................................................................................ 104 ....................................................................................................................... 104 ................................................................................ 104 ............................................................................ 104 动态语言 反射机制概念 (运行状态中知道类所有的属性和方法) 反射的应用场合 编译时类型和运行时类型 的编译时类型无法获取具体方法 Java 反射 API 反射 API 用来生成 JVM 中的类、接口或则对象的信息。 反射使用步骤(获取 Class 对象、调用对象方法) 获取 Class 对象的 3 种方法 调用某个对象的 getClass()方法 调用某个类的 class 属性来获取该类对应的 Class 对象 使用 Class 类中的 forName()静态方法(最安全/性能最好) 创建对象的两种方法 Class 对象的 newInstance() 调用 Constructor 对象的 newInstance() ........................................................................................................................ 105 ............................................................................................................................. 105 .......................................................................................................... 105 JAVA 注解 ................................................................................................................................. 106 5.1.3.1. 概念 ........................................................................................................................................................ 106 5.1.3.2. 4 种标准元注解...................................................................................................................................... 106 @Target 修饰的对象范围 ................................................................................................................................. 106 @Retention 定义 被保留的时间长短 ............................................................................................................... 106 ................................................................................................................................ 106 .............................................................................................. 106 5.1.3.3. 注解处理器............................................................................................................................................. 107 5.1.4. JAVA 内部类 ............................................................................................................................. 109 静态内部类............................................................................................................................................. 109 成员内部类............................................................................................................................................. 110 局部内部类(定义在方法中的类) ..................................................................................................... 110 匿名内部类(要继承一个父类或者实现一个接口、直接使用 new 来生成一个对象的引用) ..... 111 5.1.5. JAVA 泛型 ................................................................................................................................. 112 5.1.6. JAVA 序列化(创建可复用的 Java 对象) ................................................................................. 113 .................................................................................................... 113 ................................................................................................. 113 .................................................................................................................................. 113 Serializable 实现序列化 .................................................................................................................................... 113 ............................................... 113 ................................................................................................ 113 ............................................................................................................................................................. 113 .................................................................................................................................. 114 .............................................................................................................................................. 114 ............................................................................................ 114 5.1.7. JAVA 复制 ................................................................................................................................. 114 5.1.7.1. ......................................................................................................................................... 114 5.1.7.2. ..................................................................................... 114 5.1.7.3. ................................................................................................. 115 5.1.7.4. ........................................................................................................ 115 6. SPRING 原理 ..................................................................................................................................... 116 6.1.1. Spring 特点................................................................................................................................ 116 6.1.1.1. 轻量级 ................................................................................................................................................ 116 13/04/2018 Page 6 of 283 保存(持久化)对象及其状态到内存或者磁盘 序列化对象以字节数组保持-静态成员不保存 序列化用户远程对象传输 ObjectOutputStream 和 ObjectInputStream 对对象进行序列化及反序列化 writeObject 和 readObject 自定义序列化策略 序列化 ID 序列化并不保存静态变量 序列化子父类说明 Transient 关键字阻止该变量被序列化到文件中 直接赋值复制 浅复制(复制引用但不复制引用的对象) 深复制(复制对象和其应用对象) 序列化(深 clone 一中实现) 6.1.1.2. 6.1.1.3. 6.1.1.4. 6.1.1.5. 6.1.2. 6.1.3. 6.1.4. 6.1.5. 6.1.6. 6.1.7. ............................................................................................................................................ 116 ............................................................................................................................................ 116 .................................................................................................................................................... 116 ............................................................................................................................................ 116 Spring 核心组件........................................................................................................................ 117 Spring 常用模块........................................................................................................................ 117 Spring 主要包............................................................................................................................ 118 Spring 常用注解........................................................................................................................ 118 Spring 第三方结合.................................................................................................................... 119 Spring IOC 原理........................................................................................................................ 120 6.1.7.1. 6.1.7.2. 6.1.7.3. 概念 ........................................................................................................................................................ 120 Spring 容器高层视图 ............................................................................................................................ 120 IOC 容器实现......................................................................................................................................... 120 控制反转 面向切面 容器 框架集合 BeanFactory-框架基础设施 .............................................................................................................................. 120 1.1..1.1.1 1.1..1.1.2 1.1..1.1.3 1.1..1.1.4 1.1..1.1.5 1.1..1.1.6 1.1..1.1.7 1.1..1.1.8 BeanDefinitionRegistry 注册表................................................................................................. 121 BeanFactory 顶层接口 .............................................................................................................. 121 ListableBeanFactory ................................................................................................................. 121 HierarchicalBeanFactory 父子级联.......................................................................................... 121 ConfigurableBeanFactory......................................................................................................... 121 AutowireCapableBeanFactory 自动装配 ................................................................................ 122 SingletonBeanRegistry 运行期间注册单例 Bean................................................................... 122 依赖日志框框.............................................................................................................................122 ApplicationContext 面向开发应用 .................................................................................................................... 122 WebApplication 体系架构 ................................................................................................................................. 123 6.1.7.4. Spring Bean 作用域.............................................................................................................................. 123 singleton:单例模式(多线程下不安全) ...................................................................................................... 123 prototype:原型模式每次使用时创建 ................................................................................................................ 124 Request:一次 request 一个实例 .................................................................................................................... 124 session ................................................................................................................................................................ 124 global Session....................................................................................................................................................124 6.1.7.5. Spring Bean 生命周期.......................................................................................................................... 124 实例化.................................................................................................................................................................. 124 IOC依赖注入......................................................................................................................................................124 setBeanName 实现............................................................................................................................................ 124 BeanFactoryAware 实现 ................................................................................................................................... 124 ApplicationContextAware 实现......................................................................................................................... 125 postProcessBeforeInitialization 接口实现-初始化预处理.......................................................................... 125 init-method .......................................................................................................................................................... 125 postProcessAfterInitialization ........................................................................................................................... 125 Destroy 过期自动清理阶段 ............................................................................................................................... 125 destroy-method 自配置清理 ............................................................................................................................. 125 6.1.7.6. Spring 依赖注入四种方式 .................................................................................................................... 126 构造器注入.......................................................................................................................................................... 126 setter方法注入...................................................................................................................................................127 静态工厂注入...................................................................................................................................................... 127 实例工厂.............................................................................................................................................................. 127 6.1.7.7. 5 种不同方式的自动装配...................................................................................................................... 128 6.1.8. Spring APO 原理 ...................................................................................................................... 129 6.1.8.1. 6.1.8.2. 6.1.8.1. 概念 ........................................................................................................................................................ 129 AOP 核心概念 ....................................................................................................................................... 129 AOP 两种代理方式 ............................................................................................................................... 130 JDK 动态接口代理 ............................................................................................................................................. 130 CGLib 动态代理.................................................................................................................................................. 131 6.1.8.2. 实现原理 ................................................................................................................................................ 131 6.1.9. Spring MVC原理......................................................................................................................132 6.1.9.1. MVC 流程............................................................................................................................................... 132 Http 请求到 DispatcherServlet ....................................................................................................................... 133 HandlerMapping 寻找处理器............................................................................................................................133 调用处理器 Controller........................................................................................................................................ 133 13/04/2018 Page 7 of 283 Controller 调用业务逻辑处理后,返回 ModelAndView.................................................................................133 DispatcherServlet 查询 ModelAndView .......................................................................................................... 133 ModelAndView 反馈浏览器 HTTP ................................................................................................................... 133 6.1.9.1. MVC 常用注解 ....................................................................................................................................... 133 6.1.10. Spring Boot 原理....................................................................................................................... 134 1. 创建独立的 Spring 应用程序............................................................................................................................. 134 2.嵌入的Tomcat,无需部署WAR文件.............................................................................................................134 3. 简化 Maven 配置 ................................................................................................................................................ 134 4. 自动配置 Spring ................................................................................................................................................. 134 5. 提供生产就绪型功能,如指标,健康检查和外部配置................................................................................... 134 6. 绝对没有代码生成和对 XML 没有要求配置 [1] ............................................................................................... 134 6.1.11. JPA 原理 .................................................................................................................................... 134 6.1.11.1. 事务....................................................................................................................................................134 6.1.11.2. 6.1.11.1. 6.1.11.1. 本地事务 ............................................................................................................................................ 134 分布式事务 ........................................................................................................................................ 135 两阶段提交 ........................................................................................................................................ 136 1 准备阶段........................................................................................................................................................... 136 2 提交阶段:....................................................................................................................................................... 136 6.1.12. Mybatis 缓存.............................................................................................................................. 137 6.1.12.1. Mybatis 的一级缓存原理(sqlsession 级别)..............................................................................138 6.1.12.2. 二级缓存原理(mapper 基本).....................................................................................................138 具体使用需要配置: .......................................................................................................................................... 139 6.1.13. Tomcat 架构 .............................................................................................................................. 139 7. 微服务 ................................................................................................................................................. 140 7.1.1. 服务注册发现 ............................................................................................................................ 140
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值