分布式系統可能包含成千上萬持久對象,無限期保持所有對象激活將耗盡資源。RMI 激活機制提供:
語義保證:RMI 保持「至多一次」調用語義,失敗時保證遠程方法執行不超過一次。
activate(id, force)ActivationDesc(含組 ID、類名、codebase、初始化數據)(ActivationID, MarshalledObject) 實例化對象注意:使用激活需先運行 rmid 守護進程。
開發者需:
ActivationDesc(ActivationID, MarshalledObject)Activatable.register(ActivationDesc):不創建對象,返回 StubActivatable 構造函數(前兩種):註冊並導出對象Activatable.exportObject(前兩種):顯式導出已有實現對象特定對象僅能使用上述三種方式之一註冊。
包含:組標識符、類名、codebase、編組初始化數據、重啟模式。構造函數支持指定組 ID、重啟模式。getData() 返回 MarshalledObject,激活時傳給構造函數。
含激活器遠程引用與對象唯一標識符。activate(boolean force) 觸發激活,force=true 忽略緩存強制聯系激活組。
抽象類擴展 RemoteServer。四大構造函數:
靜態方法:register、inactive、unregister、多重 exportObject、unexportObject。
// 擴展 Activatable
public class ServerImpl extends Activatable implements Server {
// 初始構造
public ServerImpl(String codebase, MarshalledObject data)
throws ActivationException, RemoteException {
super(codebase, data, false, 0); // 匿名端口,非重啟模式
}
// 激活構造
public ServerImpl(ActivationID id, MarshalledObject data)
throws RemoteException {
super(id, 0);
// 利用 data 初始化對象狀態
}
public void doImportantStuff() { ... }
}
// 不擴展 Activatable
public class ServerImpl extends SomeClass implements Server {
public ServerImpl(String codebase, MarshalledObject data) throws ... {
Activatable.exportObject(this, codebase, data, false, 0);
}
public ServerImpl(ActivationID id, MarshalledObject data) throws ... {
Activatable.exportObject(this, id, 0);
}
...
}
ActivationDesc desc = new ActivationDesc("examples.ServerImpl", codebase, data);
Server server = (Server) Activatable.register(desc); // 返回 Stub
public interface Activator extends Remote {
MarshalledObject activate(ActivationID id, boolean force)
throws UnknownObjectException, ActivationException, RemoteException;
}
激活器緩存活動對象映射,force=false 時直接返回緩存引用。組不存在時啟動新 JVM(傳遞組描述符、化身號)。返回 MarshalledObject 避免加載對象代碼、不參與 DGC。
registerGroup/Object:註冊組/對象描述符,返回 IDactiveGroup:組回調通知已激活,返回 ActivationMonitorunregisterGroup/Object、shutdown:註銷與關閉安全限制:遠程調用上述方法拋出 AccessException。
inactiveObject(id):對象非活動,標記引用過期,下次激活重新實例化activeObject(id, mobj):對象激活,通知監控器inactiveGroup(id, incarnation):組非活動,下次用更大化身號重建public interface ActivationInstantiator extends Remote {
MarshalledObject newInstance(ActivationID id, ActivationDesc desc)
throws ActivationException, RemoteException;
}
激活組實現此接口:加載類 → 調用特殊構造函數 → 返回編組對象引用。負責報告對象非活動(調用監控器 inactiveObject)。
擴展 UnicastRemoteObject 實現 ActivationInstantiator。核心方法:
createGroup(id, desc, incarnation):創建/設置組,回調 activeGroup 獲取監控器newInstance:實例化對象(加載類、調用特殊構造函數)inactiveObject:取消導出對象,通知監控器activeObject/inactiveGroup:受保護方法供子類回調監控器默認設置 RMISecurityManager、強制系統屬性。自定義組需在構造函數設置 SecurityManager。
封裝可序列化對象,延遲至調用 get() 時反序列化。序列化時註解 codebase URL,反序列化時自動下載缺失類。遠程對象以 Stub 形式存儲。equals/hashCode 忽略 codebase 註解比較序列化內容等價性。