This commit is contained in:
@@ -29,10 +29,53 @@
|
||||
<h3>Redkale 技术详解 01 -- 双亲委托模型</h3>
|
||||
|
||||
<p>
|
||||
|
||||
Redkale 里大量使用了双亲委托模型,序列化的ConvertFactory、依赖注入的ResourceFactory、服务管理的WatchFactory均采用双亲委托模型。<br/>
|
||||
<a href="index.html" target="_blank">Redkale</a> 里大量使用了双亲委托模型,序列化的ConvertFactory、依赖注入的ResourceFactory、服务管理的WatchFactory均采用双亲委托模型。用于优先加载自定义的处理类,同时也保证两个同级的子Factory不会相互干扰。<br/>
|
||||
</p>
|
||||
|
||||
<p>ClassLoader类加载</p>
|
||||
<p>
|
||||
双亲委托模型最经典的例子就是JVM的类加载器ClassLoader。每个ClassLoader实例都有一个父类加载器的引用(不是继承关系,是包含关系),虚拟机内置的类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。当一个ClassLoader实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap ClassLoader试图加载,如果没加载到,则把任务转交给Extension ClassLoader试图加载,如果也没加载到,则转交给App ClassLoader 进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。如果它们都没有加载到这个类时,则抛出ClassNotFoundException异常。否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的Class实例对象。<br/>
|
||||
ClassLoader采用双亲委托有两个好处:避免类的重复加载和保证类的安全性。由类加载的顺序可以看出父加载器加载过的类在子加载器中不会被重复加载,同时也保证了安全性,一些非系统的class是不可靠的,若定义一个恶意的java.io.File类覆盖JDK自带的类会带来不安全性。而使用双亲委托机制的话该File类永远不会被调用,因为委托BootStrapClassLoader加载后会加载JDK中的File类而不会加载自定义的这个。
|
||||
</p>
|
||||
|
||||
<p>Redkale 双亲委托</p>
|
||||
<p>
|
||||
ConvertFactory、ResourceFactory、WatchFactory三者的双亲委托模型设计完全一样。本篇只以ConvertFactory为例说明,ConvertFactory的搜索顺序与ClassLoader相反,ClassLoader为了避免类的重复而先加载父加载器后加载子加载器,ConvertFactory为了优先加载自定义的Encoder和Decoder先搜索自身的ConvertFactory,找不到再从父ConvertFactory中搜索。
|
||||
</p>
|
||||
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">final</span> <span class="o"><</span><span class="n">E</span><span class="o">></span> <span class="n">Encodeable</span><span class="o"><</span><span class="n">W</span><span class="o">,</span> <span class="n">E</span><span class="o">></span> <span class="nf">findEncoder</span><span class="o">(</span><span class="kd">final</span> <span class="n">Type</span> <span class="n">type</span><span class="o">)</span> <span class="o">{</span>
|
||||
<span class="n">Encodeable</span><span class="o"><</span><span class="n">W</span><span class="o">,</span> <span class="n">E</span><span class="o">></span> <span class="n">rs</span> <span class="o">=</span> <span class="o">(</span><span class="n">Encodeable</span><span class="o"><</span><span class="n">W</span><span class="o">,</span> <span class="n">E</span><span class="o">>)</span> <span class="n">encoders</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">type</span><span class="o">);</span>
|
||||
<span class="k">if</span> <span class="o">(</span><span class="n">rs</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="k">return</span> <span class="n">rs</span><span class="o">;</span>
|
||||
<span class="k">return</span> <span class="k">this</span><span class="o">.</span><span class="na">parent</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">?</span> <span class="kc">null</span> <span class="o">:</span> <span class="k">this</span><span class="o">.</span><span class="na">parent</span><span class="o">.</span><span class="na">findEncoder</span><span class="o">(</span><span class="n">type</span><span class="o">);</span>
|
||||
<span class="o">}</span></pre></div>
|
||||
<p>
|
||||
当搜索不到Encoder、Decoder时,自身的ConvertFactory会自动创建一个ObjectEncoder、ObjectDecoder。
|
||||
</p>
|
||||
<div class="highlight"><pre><span class="kd">public</span> <span class="kd">final</span> <span class="o"><</span><span class="n">E</span><span class="o">></span> <span class="n">Encodeable</span><span class="o"><</span><span class="n">W</span><span class="o">,</span> <span class="n">E</span><span class="o">></span> <span class="nf">loadEncoder</span><span class="o">(</span><span class="kd">final</span> <span class="n">Type</span> <span class="n">type</span><span class="o">)</span> <span class="o">{</span>
|
||||
<span class="n">Encodeable</span><span class="o"><</span><span class="n">W</span><span class="o">,</span> <span class="n">E</span><span class="o">></span> <span class="n">encoder</span> <span class="o">=</span> <span class="n">findEncoder</span><span class="o">(</span><span class="n">type</span><span class="o">);</span>
|
||||
<span class="k">if</span> <span class="o">(</span><span class="n">encoder</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="k">return</span> <span class="n">encoder</span><span class="o">;</span>
|
||||
<span class="k">if</span> <span class="o">(</span><span class="n">type</span> <span class="k">instanceof</span> <span class="n">GenericArrayType</span><span class="o">)</span> <span class="k">return</span> <span class="k">new</span> <span class="nf">ArrayEncoder</span><span class="o">(</span><span class="k">this</span><span class="o">,</span> <span class="n">type</span><span class="o">);</span>
|
||||
<span class="n">Class</span> <span class="n">clazz</span><span class="o">;</span>
|
||||
<span class="k">if</span> <span class="o">(</span><span class="n">type</span> <span class="k">instanceof</span> <span class="n">ParameterizedType</span><span class="o">)</span> <span class="o">{</span>
|
||||
<span class="kd">final</span> <span class="n">ParameterizedType</span> <span class="n">pts</span> <span class="o">=</span> <span class="o">(</span><span class="n">ParameterizedType</span><span class="o">)</span> <span class="n">type</span><span class="o">;</span>
|
||||
<span class="n">clazz</span> <span class="o">=</span> <span class="o">(</span><span class="n">Class</span><span class="o">)</span> <span class="o">(</span><span class="n">pts</span><span class="o">).</span><span class="na">getRawType</span><span class="o">();</span>
|
||||
<span class="o">}</span> <span class="k">else</span> <span class="nf">if</span> <span class="o">(</span><span class="n">type</span> <span class="k">instanceof</span> <span class="n">TypeVariable</span><span class="o">)</span> <span class="o">{</span>
|
||||
<span class="n">TypeVariable</span> <span class="n">tv</span> <span class="o">=</span> <span class="o">(</span><span class="n">TypeVariable</span><span class="o">)</span> <span class="n">type</span><span class="o">;</span>
|
||||
<span class="n">Type</span> <span class="n">t</span> <span class="o">=</span> <span class="n">Object</span><span class="o">.</span><span class="na">class</span><span class="o">;</span>
|
||||
<span class="k">if</span> <span class="o">(</span><span class="n">tv</span><span class="o">.</span><span class="na">getBounds</span><span class="o">().</span><span class="na">length</span> <span class="o">==</span> <span class="mi">1</span><span class="o">)</span> <span class="o">{</span>
|
||||
<span class="n">t</span> <span class="o">=</span> <span class="n">tv</span><span class="o">.</span><span class="na">getBounds</span><span class="o">()[</span><span class="mi">0</span><span class="o">];</span>
|
||||
<span class="o">}</span>
|
||||
<span class="k">if</span> <span class="o">(!(</span><span class="n">t</span> <span class="k">instanceof</span> <span class="n">Class</span><span class="o">))</span> <span class="n">t</span> <span class="o">=</span> <span class="n">Object</span><span class="o">.</span><span class="na">class</span><span class="o">;</span>
|
||||
<span class="n">clazz</span> <span class="o">=</span> <span class="o">(</span><span class="n">Class</span><span class="o">)</span> <span class="n">t</span><span class="o">;</span>
|
||||
<span class="o">}</span> <span class="k">else</span> <span class="nf">if</span> <span class="o">(</span><span class="n">type</span> <span class="k">instanceof</span> <span class="n">Class</span><span class="o">)</span> <span class="o">{</span>
|
||||
<span class="n">clazz</span> <span class="o">=</span> <span class="o">(</span><span class="n">Class</span><span class="o">)</span> <span class="n">type</span><span class="o">;</span>
|
||||
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
|
||||
<span class="k">throw</span> <span class="k">new</span> <span class="nf">ConvertException</span><span class="o">(</span><span class="s">"not support the type ("</span> <span class="o">+</span> <span class="n">type</span> <span class="o">+</span> <span class="s">")"</span><span class="o">);</span>
|
||||
<span class="o">}</span>
|
||||
<span class="n">encoder</span> <span class="o">=</span> <span class="n">findEncoder</span><span class="o">(</span><span class="n">clazz</span><span class="o">);</span>
|
||||
<span class="k">if</span> <span class="o">(</span><span class="n">encoder</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="k">return</span> <span class="n">encoder</span><span class="o">;</span>
|
||||
<span class="k">return</span> <span class="nf">createEncoder</span><span class="o">(</span><span class="n">type</span><span class="o">,</span> <span class="n">clazz</span><span class="o">);</span>
|
||||
<span class="o">}</span></pre></div>
|
||||
|
||||
<footer class="site-footer">
|
||||
<span class="site-footer-owner"> 欢迎加入Redkale QQ群: 527523235</span>
|
||||
</footer>
|
||||
|
||||
@@ -26,20 +26,19 @@
|
||||
</section>
|
||||
|
||||
<section class="main-content">
|
||||
<!--
|
||||
|
||||
<p class="art-list">
|
||||
<a href="article_parents.html" target="_blank" class="art-title">Redkale 技术详解 01 -- 双亲委托模型</a>
|
||||
<label class="art-date">2016-02</label><br/>
|
||||
<label class="art-desc">Redkale 里大量使用了双亲委托模型,序列化的ConvertFactory、依赖注入的ResourceFactory、服务管理的WatchFactory均采用双亲委托模型。</label>
|
||||
</p>
|
||||
|
||||
<!--
|
||||
<p class="art-list">
|
||||
<a href="article_creator.html" target="_blank" class="art-title">Redkale 技术详解 02 -- Creator对象构造</a>
|
||||
<label class="art-date">2016-02</label><br/>
|
||||
<label class="art-desc">...</label>
|
||||
</p>
|
||||
-->
|
||||
<p>敬请期待……</p>
|
||||
|
||||
<br/>
|
||||
<footer class="site-footer">
|
||||
|
||||
Reference in New Issue
Block a user