-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
331 lines (191 loc) · 33 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>偷得浮生一日闲</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta property="og:type" content="website">
<meta property="og:title" content="偷得浮生一日闲">
<meta property="og:url" content="http://example.com/index.html">
<meta property="og:site_name" content="偷得浮生一日闲">
<meta property="og:locale" content="en_US">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
<link rel="alternate" href="/atom.xml" title="偷得浮生一日闲" type="application/atom+xml">
<link rel="shortcut icon" href="/favicon.png">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">
<meta name="generator" content="Hexo 7.2.0"></head>
<body>
<div id="container">
<div id="wrap">
<header id="header">
<div id="banner"></div>
<div id="header-outer" class="outer">
<div id="header-title" class="inner">
<h1 id="logo-wrap">
<a href="/" id="logo">偷得浮生一日闲</a>
</h1>
</div>
<div id="header-inner" class="inner">
<nav id="main-nav">
<a id="main-nav-toggle" class="nav-icon"><span class="fa fa-bars"></span></a>
<a class="main-nav-link" href="/">Home</a>
<a class="main-nav-link" href="/archives">Archives</a>
</nav>
<nav id="sub-nav">
<a class="nav-icon" href="/atom.xml" title="RSS Feed"><span class="fa fa-rss"></span></a>
<a class="nav-icon nav-search-btn" title="Search"><span class="fa fa-search"></span></a>
</nav>
<div id="search-form-wrap">
<form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit"></button><input type="hidden" name="sitesearch" value="http://example.com"></form>
</div>
</div>
</div>
</header>
<div class="outer">
<section id="main">
<article id="post-java双亲委派模式" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2024/05/09/java%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%A8%A1%E5%BC%8F/" class="article-date">
<time class="dt-published" datetime="2024-05-09T12:37:36.000Z" itemprop="datePublished">2024-05-09</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2024/05/09/java%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%A8%A1%E5%BC%8F/">java双亲委派模式</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<h1 id="为什么需要双亲委派机制"><a href="#为什么需要双亲委派机制" class="headerlink" title="为什么需要双亲委派机制"></a>为什么需要双亲委派机制</h1><p><strong>双亲委派机制</strong>是Java虚拟机(JVM)中的一种类加载机制。</p>
<p>在Java中,类加载器(ClassLoader)负责将类的字节码加载到内存中,并创建对应的Class对象。当一个类被加载时,JVM会按照一定的顺序去搜索类的定义。双亲委派机制就是基于这种搜索顺序来工作的。</p>
<p>具体来说,当一个类加载器收到加载类的请求时,它首先会将这个请求委派给它的父类加载器去处理。如果父类加载器能够找到并加载这个类,那么加载过程就结束了。如果父类加载器无法找到这个类,那么子类加载器才会尝试加载这个类。</p>
<p>这种双亲委派机制的好处在于可以避免类的重复加载和冲突。当一个类被加载后,它会被缓存起来,下次再次加载时可以直接使用缓存的结果,提高了加载的效率。另外,由于父类加载器优先加载类,所以可以保证类的一致性,避免了不同类加载器加载同一个类的问题。</p>
<p>双亲委派机制还有助于保护核心类库的安全性。JVM中有一个根类加载器(Bootstrap ClassLoader),它负责加载核心类库,如java.lang包下的类。由于根类加载器是由JVM实现的,无法通过Java代码直接访问,因此可以防止恶意代码替换核心类库。</p>
<p><strong>总结</strong></p>
<ul>
<li><strong>解决类加载的冲突和重复加载的问题</strong>。</li>
<li><strong>沙箱安全机制:防止Java核心API库被随意篡改。通俗点说,当Java核心类库中的类(比如:java.lang.String)的类名与用户自定义类的类名相同有冲突时,Java不会加载用户自定义的类。</strong></li>
</ul>
<h1 id="java中双亲委派机制如何实现的"><a href="#java中双亲委派机制如何实现的" class="headerlink" title="java中双亲委派机制如何实现的"></a>java中双亲委派机制如何实现的</h1><img src="/2024/05/09/java%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%A8%A1%E5%BC%8F/%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8%E7%A4%BA%E6%84%8F%E5%9B%BE.png" class="" title="This is an example image">
<p>在java中的类加载器模型图如上,分为三层。</p>
<p>BootstrapClassLoader: 启动类加载器,最上层类加载器为本地方法,主要加载 jre/lib/rt.jar 路径内类文件</p>
<p>ExtClassLoader:扩展类加载器 主要加载 jre/lib/ext/*.jar</p>
<p>AppClassLoader: 用来加载CLASS_PATH 下所有jar,即项目所有class</p>
<p>UserClassLoader: 自定义类加载器,该类加载器是否遵循类加载机制,或特殊操作可以自己实现,打破类加载机机制也由该类加载器实现。</p>
<h2 id="源码解析"><a href="#源码解析" class="headerlink" title="源码解析"></a>源码解析</h2><p>测试代码如下</p>
<p> 尝试用AppClassLoader 去加载 java.lang.String</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Main</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> ClassNotFoundException {</span><br><span class="line"></span><br><span class="line"> <span class="type">ClassLoader</span> <span class="variable">appClassLoader</span> <span class="operator">=</span> Main.class.getClassLoader();</span><br><span class="line"> <span class="comment">// AppClassLoader</span></span><br><span class="line"> System.out.println(<span class="string">"当前类加载器为:"</span> + appClassLoader);</span><br><span class="line"></span><br><span class="line"> Class<?> aClass = appClassLoader.loadClass(<span class="string">"java.lang.String"</span>);</span><br><span class="line"> <span class="type">ClassLoader</span> <span class="variable">StringClassLoader</span> <span class="operator">=</span> aClass.getClassLoader();</span><br><span class="line"> System.out.println(<span class="string">"String类加载器为:"</span> + StringClassLoader);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>测试结果:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">当前类加载器为:sun.misc.Launcher$AppClassLoader@14dad5dc</span><br><span class="line">String类加载器为:null</span><br></pre></td></tr></table></figure>
<p>解释: </p>
<p>因为<code>String</code>类是由引导类加载器加载的,这个类加载器是JVM的一部分,不是一个标准的Java类加载器。由引导类加载器加载的类不会有一个对应的类加载器实例,因此返回<code>null</code>。</p>
<p>类加载机制关键方法为loadClass, 接下来进行刨析jkd源码,去探索jdk如何实现的双亲委派机制</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">AppClassLoader</span> <span class="keyword">extends</span> <span class="title class_">URLClassLoader</span> {</span><br><span class="line"> <span class="comment">// 获取当前项目lib 及本身项目jar包路径</span></span><br><span class="line"> <span class="keyword">final</span> <span class="type">URLClassPath</span> <span class="variable">ucp</span> <span class="operator">=</span> SharedSecrets.getJavaNetAccess().getURLClassPath(<span class="built_in">this</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> ClassLoader <span class="title function_">getAppClassLoader</span><span class="params">(<span class="keyword">final</span> ClassLoader var0)</span> <span class="keyword">throws</span> IOException {</span><br><span class="line"> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">var1</span> <span class="operator">=</span> System.getProperty(<span class="string">"java.class.path"</span>);</span><br><span class="line"> <span class="keyword">final</span> File[] var2 = var1 == <span class="literal">null</span> ? <span class="keyword">new</span> <span class="title class_">File</span>[<span class="number">0</span>] : Launcher.getClassPath(var1);</span><br><span class="line"> <span class="keyword">return</span> (ClassLoader)AccessController.doPrivileged(<span class="keyword">new</span> <span class="title class_">PrivilegedAction</span><AppClassLoader>() {</span><br><span class="line"> <span class="keyword">public</span> AppClassLoader <span class="title function_">run</span><span class="params">()</span> {</span><br><span class="line"> URL[] var1x = var1 == <span class="literal">null</span> ? <span class="keyword">new</span> <span class="title class_">URL</span>[<span class="number">0</span>] : Launcher.pathToURLs(var2);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">AppClassLoader</span>(var1x, var0);</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> AppClassLoader(URL[] var1, ClassLoader var2) {</span><br><span class="line"> <span class="built_in">super</span>(var1, var2, Launcher.factory);</span><br><span class="line"> <span class="built_in">this</span>.ucp.initLookupCache(<span class="built_in">this</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> Class<?> loadClass(String var1, <span class="type">boolean</span> var2) <span class="keyword">throws</span> ClassNotFoundException {</span><br><span class="line"> <span class="type">int</span> <span class="variable">var3</span> <span class="operator">=</span> var1.lastIndexOf(<span class="number">46</span>);</span><br><span class="line"> <span class="keyword">if</span> (var3 != -<span class="number">1</span>) {</span><br><span class="line"> <span class="type">SecurityManager</span> <span class="variable">var4</span> <span class="operator">=</span> System.getSecurityManager();</span><br><span class="line"> <span class="keyword">if</span> (var4 != <span class="literal">null</span>) {</span><br><span class="line"> var4.checkPackageAccess(var1.substring(<span class="number">0</span>, var3));</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 判断当前项目 及 lib目录下有没有java.lang.String 显然没有</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">this</span>.ucp.knownToNotExist(var1)) {</span><br><span class="line"> <span class="type">Class</span> <span class="variable">var5</span> <span class="operator">=</span> <span class="built_in">this</span>.findLoadedClass(var1);</span><br><span class="line"> <span class="keyword">if</span> (var5 != <span class="literal">null</span>) {</span><br><span class="line"> <span class="keyword">if</span> (var2) {</span><br><span class="line"> <span class="built_in">this</span>.resolveClass(var5);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> var5;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">ClassNotFoundException</span>(var1);</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// 调用父类loadClass, 父类loadClass 方法内就包含了双亲委派机制</span></span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">super</span>.loadClass(var1, var2);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">protected</span> PermissionCollection <span class="title function_">getPermissions</span><span class="params">(CodeSource var1)</span> {</span><br><span class="line"> <span class="type">PermissionCollection</span> <span class="variable">var2</span> <span class="operator">=</span> <span class="built_in">super</span>.getPermissions(var1);</span><br><span class="line"> var2.add(<span class="keyword">new</span> <span class="title class_">RuntimePermission</span>(<span class="string">"exitVM"</span>));</span><br><span class="line"> <span class="keyword">return</span> var2;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">appendToClassPathForInstrumentation</span><span class="params">(String var1)</span> {</span><br><span class="line"> <span class="keyword">assert</span> Thread.holdsLock(<span class="built_in">this</span>);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">super</span>.addURL(Launcher.getFileURL(<span class="keyword">new</span> <span class="title class_">File</span>(var1)));</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> AccessControlContext <span class="title function_">getContext</span><span class="params">(File[] var0)</span> <span class="keyword">throws</span> MalformedURLException {</span><br><span class="line"> <span class="type">PathPermissions</span> <span class="variable">var1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">PathPermissions</span>(var0);</span><br><span class="line"> <span class="type">ProtectionDomain</span> <span class="variable">var2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ProtectionDomain</span>(<span class="keyword">new</span> <span class="title class_">CodeSource</span>(var1.getCodeBase(), (Certificate[])<span class="literal">null</span>), var1);</span><br><span class="line"> <span class="type">AccessControlContext</span> <span class="variable">var3</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AccessControlContext</span>(<span class="keyword">new</span> <span class="title class_">ProtectionDomain</span>[]{var2});</span><br><span class="line"> <span class="keyword">return</span> var3;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">static</span> {</span><br><span class="line"> ClassLoader.registerAsParallelCapable();</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>父类方法如下</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">protected</span> Class<?> loadClass(String name, <span class="type">boolean</span> resolve)</span><br><span class="line"> <span class="keyword">throws</span> ClassNotFoundException</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">synchronized</span> (getClassLoadingLock(name)) {</span><br><span class="line"> <span class="comment">// First, check if the class has already been loaded</span></span><br><span class="line"> <span class="comment">// 首先检查是否已经被本类加载器加载过了,findLoadedClass 本地方法不去关注</span></span><br><span class="line"> Class<?> c = findLoadedClass(name);</span><br><span class="line"> <span class="keyword">if</span> (c == <span class="literal">null</span>) {</span><br><span class="line"> <span class="type">long</span> <span class="variable">t0</span> <span class="operator">=</span> System.nanoTime();</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="comment">// 如果父类加载器不为空就调用 父类加载器的loadClass方法,即委托父类去加载</span></span><br><span class="line"> <span class="keyword">if</span> (parent != <span class="literal">null</span>) {</span><br><span class="line"> c = parent.loadClass(name, <span class="literal">false</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// 如果父类加载器为空就调用 BootstraploadClass方法,即委托Bootstrap类加载器去加载</span></span><br><span class="line"> c = findBootstrapClassOrNull(name);</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">catch</span> (ClassNotFoundException e) {</span><br><span class="line"> <span class="comment">// ClassNotFoundException thrown if class not found</span></span><br><span class="line"> <span class="comment">// from the non-null parent class loader</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (c == <span class="literal">null</span>) {</span><br><span class="line"> <span class="comment">// If still not found, then invoke findClass in order</span></span><br><span class="line"> <span class="comment">// to find the class.</span></span><br><span class="line"> <span class="type">long</span> <span class="variable">t1</span> <span class="operator">=</span> System.nanoTime();</span><br><span class="line"> c = findClass(name);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// this is the defining class loader; record the stats</span></span><br><span class="line"> sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);</span><br><span class="line"> sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);</span><br><span class="line"> sun.misc.PerfCounter.getFindClasses().increment();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (resolve) {</span><br><span class="line"> resolveClass(c);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> c;</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>从上述源码显而易见,双亲委派机制本质上就是一个责任链, 每个子类加载器中都包含父类加载器, 一层层递归调用上去实现了双亲委派机制,既然了解了该机制那么破坏双亲委派机制就很简单了,只需要重写该方法时候不去调用parent.loadClass(name, false)即可。</p>
<h1 id="为什么需要破坏双亲委派机制"><a href="#为什么需要破坏双亲委派机制" class="headerlink" title="为什么需要破坏双亲委派机制"></a>为什么需要破坏双亲委派机制</h1><p>目前我接触到的主要是为了解决类加载冲突:</p>
<p>例如:</p>
<p>1.在<a target="_blank" rel="noopener" href="https://www.baidu.com/s?rsv_idx=1&wd=Tomcat&fenlei=256&usm=1&ie=utf-8&rsv_pq=a7e3089400508c19&oq=%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81%E7%A0%B4%E5%9D%8F%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%9C%BA%E5%88%B6&rsv_t=72ec6RJWthdLwxwGhlDtXuAxsmOk2aRSy5IYSAV2SwMP9+HCDp8c9QQmHAI&sa=re_dqa_zy&icon=1">Tomcat<em></em></a>中,不同的Web应用程序可能使用不同版本的jar包</p>
<p>2.javaAgent技术中引入三方依赖极易产生jar包冲突等现象,所以需要破坏双亲委派机制 例如sermant <a target="_blank" rel="noopener" href="https://bbs.huaweicloud.com/blogs/410414">https://bbs.huaweicloud.com/blogs/410414</a> 讲解很不错</p>
<h1 id="如何破坏类加载机制"><a href="#如何破坏类加载机制" class="headerlink" title="如何破坏类加载机制"></a>如何破坏类加载机制</h1><p>暂无</p>
</div>
<footer class="article-footer">
<a data-url="http://example.com/2024/05/09/java%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%A8%A1%E5%BC%8F/" data-id="clw22xh4q0002uwulb1nw3p8t" data-title="java双亲委派模式" class="article-share-link"><span class="fa fa-share">Share</span></a>
</footer>
</div>
</article>
<article id="post-Spring-Framework-源码学习一" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2024/04/25/Spring-Framework-%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E4%B8%80/" class="article-date">
<time class="dt-published" datetime="2024-04-25T13:50:38.000Z" itemprop="datePublished">2024-04-25</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2024/04/25/Spring-Framework-%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E4%B8%80/">Spring Framework 源码学习一</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
</div>
<footer class="article-footer">
<a data-url="http://example.com/2024/04/25/Spring-Framework-%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E4%B8%80/" data-id="clw22xh4i0000uwulhskqgt1h" data-title="Spring Framework 源码学习一" class="article-share-link"><span class="fa fa-share">Share</span></a>
</footer>
</div>
</article>
<article id="post-hello-world" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
<div class="article-meta">
<a href="/2024/04/25/hello-world/" class="article-date">
<time class="dt-published" datetime="2024-04-25T13:30:36.899Z" itemprop="datePublished">2024-04-25</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="p-name article-title" href="/2024/04/25/hello-world/">Hello World</a>
</h1>
</header>
<div class="e-content article-entry" itemprop="articleBody">
<p>Welcome to <a target="_blank" rel="noopener" href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a target="_blank" rel="noopener" href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a target="_blank" rel="noopener" href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a target="_blank" rel="noopener" href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p>
<h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure>
<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/writing.html">Writing</a></p>
<h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure>
<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/server.html">Server</a></p>
<h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure>
<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/generating.html">Generating</a></p>
<h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure>
<p>More info: <a target="_blank" rel="noopener" href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>
</div>
<footer class="article-footer">
<a data-url="http://example.com/2024/04/25/hello-world/" data-id="clw22xh4m0001uwulfzofgwj7" data-title="Hello World" class="article-share-link"><span class="fa fa-share">Share</span></a>
</footer>
</div>
</article>
</section>
<aside id="sidebar">
<div class="widget-wrap">
<h3 class="widget-title">Archives</h3>
<div class="widget">
<ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2024/05/">May 2024</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2024/04/">April 2024</a></li></ul>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">Recent Posts</h3>
<div class="widget">
<ul>
<li>
<a href="/2024/05/09/java%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%A8%A1%E5%BC%8F/">java双亲委派模式</a>
</li>
<li>
<a href="/2024/04/25/Spring-Framework-%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0%E4%B8%80/">Spring Framework 源码学习一</a>
</li>
<li>
<a href="/2024/04/25/hello-world/">Hello World</a>
</li>
</ul>
</div>
</div>
</aside>
</div>
<footer id="footer">
<div class="outer">
<div id="footer-info" class="inner">
© 2024 John Doe<br>
Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
</div>
</div>
</footer>
</div>
<nav id="mobile-nav">
<a href="/" class="mobile-nav-link">Home</a>
<a href="/archives" class="mobile-nav-link">Archives</a>
</nav>
<script src="/js/jquery-3.6.4.min.js"></script>
<script src="/fancybox/jquery.fancybox.min.js"></script>
<script src="/js/script.js"></script>
</div>
</body>
</html>