了解javaScript 在查询数据时, 运行的核心机制 及 引起冲突可能的原因

项目场景:

项目相关背景:

javaScript 在查询数据时, 运行的核心机制


一、核心机制

**
javaScript 在查询数据时,有时会遇到查询异常或失败的问题,在解决问题之前,我们需要先了解下 javaScript 在查询数据时, 运行的核心机制相关的知识

**

(1)、双亲委派原则

JAVA运行的本质:
Java是运行在Java的虚拟机(JVM)中的。

首先,我们编写的Java源代码被会被编译器编译成.class的字节码文件。
然后再由ClassLoader负责将这些 .class 文件加载到JVM中去执行。

当某个 ClassLoader 需要加载某个 .class 文件时,它首先把这个任务委托给他的上级 ClassLoader ,递归这个操作,如果上级的 ClassLoader 没有加载,自己才会去加载这个类。

JVM中提供了三层的 ClassLoader:

1)、ClassLoader 作用以及加载范围
Bootstrap classLoader c++编写,是用本地代码实现的类装入器,负责在虚拟机启动时加载Jdk核心类库(如:rt.jar、resources.jar、charsets.jar等)以及加载后两个类加载器。
由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,
所以不允许直接通过引用进行操作。

ExtClassLoader java编写,是一个普通的Java类,继承自ClassLoader类,负责加载{JAVA_HOME}/jre/lib/ext/目录下的所有jar包。

AppClassLoader java编写,是Extension ClassLoader的子对象,
负责加载应用程序classpath目录下的所有jar和class文件。

每次收到类加载请求时,先将请求委派给父类加载器完成(所有加载请求最终会委派到顶层的Bootstrap ClassLoader加载器中),如果父类加载器无法完成这个加载(该加载器的搜索范围中没有找到对应的类),子类尝试自己加载, 如果都没加载到,则会抛出 ClassNotFoundException 异常。

双亲委派原则在本质上,是为了避免动态重复加载而考虑的一个安全因素。
很多系统的关键类,如String 已经在启动时就被引导类加载器(Bootstrcp ClassLoader)加载,所以用户自定义的ClassLoader永远也无法加载一个自己写的String。

(2)、加载器加载原则

加载器加载的原则指的是:
在同一个目录下,jvm加载jar包顺序是无法保证的,每个系统的都不一样,甚至同一个系统不同的时刻加载都不一样。
良好设计的系统不应该依赖任何特定的加载顺序。

也就是说,Java类加载器加载同一个目录下的jar包的顺序是随机的,会受操作系统的文件系统影响。

(3)、Maven的依赖规则

>1、短路优先(就近原则)

假如:A依赖B,B依赖C,C依赖X1(jar) :A 一> B 一> C 一>X(1.0版本 jar)
假如:A依赖D,D依赖X2(jar) :A 一> D 一>X(2.0版本 jar)

则,X(2.0版本 jar) 将会被Maven解析

>2、先声明先优先

如果路径相同,则谁先优先声明,谁就将会被解析

实际上,Maven的依赖规则也是为了避免jar冲突,但是有些时候现实业务场景往往比较复杂,类似上述第二条规则,实际上并不是一种合理的解决方案,只能说是一种无奈的解决方式。

二、冲突本质

(1)、不同版本的jar包冲突

假如 pom.xml 添加依赖:A 、D

假如:A 一> B 一>M(2.0版本 jar)
假如:D 一> M (1.0版本 jar)

当pom.xml文件中引入A、D两个依赖后,根据Maven传递依赖的原则,两个版本的M都被间接依赖,而最终M (1.0版本 jar)会被Maven的就近原则被引入。

此时,当 JVM 加载 B 中的某个类,而该类调用 M 中的某个类的某个方法 f() 时,注意,该方法可能是在 M(2.0版本 jar) 才提供的方法,但是目前项目依赖的M版本则是 1.0 ,的方法。这样 JVM 在加载的时候,找不到 f() 方法,就会报NoSuchMethodError的错误,此时就产生了jar包冲突。

这也是我们最常见的一种冲突。

(2)、相同全限定名的类的冲突

同样的类(类的全限定名完全一样)出现在多个不同的依赖Jar包中,即该类有多个版本,并由于Jar包加载的先后顺序导致JVM加载了错误版本的类。
注意:本文所有的分析都基于 idea 编辑器中 可能出现的问题 及相关问题的解决方式。

三、解决冲突

主要介绍第一种方式:手动排除

(1)、手动排除

首先,你可以通过 IDEA 的 Maven dependency tree 来排查存在的冲突可能,进而排查冲突。

我们首先来看下项目 中 的Maven jar包依赖树
在这里插入图片描述
如何查看项目中的 Maven jar包依赖树
打开 IDEA,温馨提示:本文所有的分析都基于 idea 编辑器中,不同的编辑器可能会存在不同的 问题,查看依赖树的方式 及 生成的 dependency tree 也有可能 有所差异。
所以应注意 我们的环境 是否一致。
在这里插入图片描述
截取 Maven dependency tree 中的一小部分,简单分析如下:
在这里插入图片描述

注意:图中用红色线条标出的部分 代表的是前后不同使用的版本号

你可以直接右键相应的jar,选择 “Exclude” 进行排除:

在这里插入图片描述

上述的排除方式,实际上也就是在 pom.xml 中为你在相应的 jar 下添加 “exclusion” 标签,你也可以自己手动添加该标签,效果是一样的。
如下:

代码示例如下:

 <dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>${shiro.version}</version>
</dependency>

项目截取部分截图如下:
在这里插入图片描述
在这里插入图片描述

使用maven的 “artifactId” 中的内容进行排查(注:有的编辑规则不同,可以通过“exclusion” 标签进行排查) 标签指定版本排除依赖是否重复,版本存在差异问题。

**

(2)、使用插件

**
解决包冲突的插件有如下,具体的使用方式可自行百度,具体原理和上述方法<1>类似。

maven-enforcer-plugin插件
Maven Helper


因项目不同,开发使用的场景不同,如查询数据时遇到相关的问题。
我们要 慢慢去排查问题, 然后分析原因后进行解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值