Redkale 裏大量使用了雙親委託模型,序列化的ConvertFactory、依賴注入的ResourceFactory、服務管理的WatchFactory均採用雙親委託模型。用於優先加載自定義的處理類,同時也保證兩個同級的子Factory不會相互干擾。
html
ClassLoader類加載java
雙親委託模型最經典的例子就是JVM的類加載器ClassLoader。每一個ClassLoader實例都有一個父類加載器的引用(不是繼承關係,是包含關係),虛擬機內置的類加載器(Bootstrap ClassLoader)自己沒有父類加載器,但能夠用做其它ClassLoader實例的的父類加載器。當一個ClassLoader實例須要加載某個類時,它會試圖親自搜索某個類以前,先把這個任務委託給它的父類加載器,這個過程是由上至下依次檢查的,首先由最頂層的類加載器Bootstrap ClassLoader試圖加載,若是沒加載到,則把任務轉交給Extension ClassLoader試圖加載,若是也沒加載到,則轉交給App ClassLoader 進行加載,若是它也沒有加載獲得的話,則返回給委託的發起者,由它到指定的文件系統或網絡等URL中加載該類。若是它們都沒有加載到這個類時,則拋出ClassNotFoundException異常。不然將這個找到的類生成一個類的定義,並將它加載到內存當中,最後返回這個類在內存中的Class實例對象。
ClassLoader採用雙親委託有兩個好處:避免類的重複加載和保證類的安全性。由類加載的順序能夠看出父加載器加載過的類在子加載器中不會被重複加載,同時也保證了安全性,一些非系統的class是不可靠的,若定義一個惡意的java.io.File類覆蓋JDK自帶的類會帶來不安全性。而使用雙親委託機制的話該File類永遠不會被調用,由於委託BootStrapClassLoader加載後會加載JDK中的File類而不會加載自定義的這個。安全
Redkale 雙親委託網絡
ConvertFactory、ResourceFactory、WatchFactory三者的雙親委託模型設計徹底同樣。下面以ConvertFactory爲例說明,ConvertFactory的搜索順序與ClassLoader相反,ClassLoader爲了不類的重複而先加載父加載器後加載子加載器,ConvertFactory爲了優先加載自定義的Encoder和Decoder先搜索自身的ConvertFactory,找不到再從父ConvertFactory中搜索。app
public final <E> Encodeable<W, E> findEncoder(final Type type) {
Encodeable<W, E> rs = (Encodeable<W, E>) encoders.get(type);
if (rs != null) return rs;
return this.parent == null ? null : this.parent.findEncoder(type);
}
當搜索不到Encoder、Decoder時,自身的ConvertFactory會自動建立一個ObjectEncoder、ObjectDecoder。this
public final <E> Encodeable<W, E> loadEncoder(final Type type) {
Encodeable<W, E> encoder = findEncoder(type);
if (encoder != null) return encoder;
if (type instanceof GenericArrayType) return new ArrayEncoder(this, type);
Class clazz;
if (type instanceof ParameterizedType) {
final ParameterizedType pts = (ParameterizedType) type;
clazz = (Class) (pts).getRawType();
} else if (type instanceof TypeVariable) {
TypeVariable tv = (TypeVariable) type;
Type t = Object.class;
if (tv.getBounds().length == 1) {
t = tv.getBounds()[0];
}
if (!(t instanceof Class)) t = Object.class;
clazz = (Class) t;
} else if (type instanceof Class) {
clazz = (Class) type;
} else {
throw new ConvertException("not support the type (" + type + ")");
}
encoder = findEncoder(clazz);
if (encoder != null) return encoder;
return createEncoder(type, clazz);
}
大部分狀況下Convert的處理對象會根據JavaBean類自定生成,而有些場景須要覆蓋處理類,這樣須要子ConvertFactory,如 Convert基本用法 例子中使用JsonFactory.root().createChild()重定義。且與JsonFactory.root()中的定義能夠並存,也不會產出衝突。spa
Redkale能夠啓動多個協議Server服務(配置文件中含多個server節點),爲避免衝突,每一個非SNCP的Server的ResourceFactory也是獨立的。設計
public NodeServer(Application application, Server server) {
this.application = application;
this.resourceFactory = application.getResourceFactory().createChild();
this.server = server;
this.logger = Logger.getLogger(this.getClass().getSimpleName());
}
雙親委託模型既可以讓同級子Factory保持獨立,也可重用父Factory內的配置,所以在Redkale這種支持多Server、多種配置的場景下非常適合。code
轉載請註明出處:http://redkale.org/article_parents.htmlorm