gpt4 book ai didi

java - 让子类序列化为父类(super class)的实例?

转载 作者:行者123 更新时间:2023-12-02 11:08:18 24 4
gpt4 key购买 nike

我正在处理一个已构建 MBean 的代码库(用于导出到 jmx)。

原始代码只是构建一个 MBeanInfo 实例:

@Override
public MBeanInfo getMBeanInfo() {
MBeanAttributeInfo[] attrs = //SLOW TO BUILD
return new MBeanInfo(...attrs...);
}

由于构建 mbean 属性的成本很高,并且该方法被调用得相当频繁(即使没有附加 jmx 客户端),因此我尝试创建 MBeanInto 的子类来延迟计算这些属性:

public class LazyMBeanInfo extends MBeanInfo implements Externalizable {
private transient AttributeCallback callback = null;
private volatile MBeanAttributeInfo[] lazyAttrs = null;

public LazyMBeanInfo(...AttributeCallback callback...) throws IllegalArgumentException {
super(className, description, null, constructors, operations, notifications);
this.callback = callback;
}

@Override
public MBeanAttributeInfo[] getAttributes() {
MBeanAttributeInfo[] val = lazyAttrs;
if (val != null) {
return val.clone(); //match upstream behaviour
}
if (callback == null) {
throw new IllegalStateException("BUG");
}
val = callback.buildAttributes();
if (val == null) {
val = new MBeanAttributeInfo[0];
}
lazyAttrs = val;
return val.clone();
}

public interface AttributeCallback {
MBeanAttributeInfo[] buildAttributes();
}
}

问题是 JMX(通过 RMI)序列化 MBeanInfo 对象,然后在 jconsole(或 jvisualVM)中出现错误: enter image description here

那么 - 我可以以某种方式实现Externalized并将自己序列化为父类的实例吗?理想情况下,我希望它能够工作:

public class LazyMBeanInfo extends MBeanInfo implements Externalizable {
//same as before, plus:
@Override
public void writeExternal(ObjectOutput out) throws IOException {
MBeanInfo vanilla = new MBeanInfo(...);
out.writeObject(vanilla);
}
}

但事实并非如此。

这可能吗?

最佳答案

除非您使用[高度动态] DynamicMBeans,否则我不明白为什么每次调用 getMBeanInfo() 时都需要重建 MBeanInfo,但是......

您的 LazyMBeanInfo 可以正常工作(尽管我尚未测试此特定情况)。 MBeanInfo 已经实现了 Serialized,因此您想要的是序列化过程写出 MBeanInfo,而不是 LazyMBeanInfo,因为客户端的类路径中可能没有该类。然而,LazyMBeanInfo可以实现这个方法:

Object writeReplace() throws ObjectStreamException;

此时您将写出底层 MBeanInfo。请参阅Serializable JavaDoc,具体来说:

Serializable classes that need to designate an alternative object to be used when writing an object to the stream should implement this special method with the exact signature:

ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;

这样,实际的对象可以是 LazyMBeanInfo 的实例,但您写出的内容可以是实际的 MBeanInfo,它是根据缓存的lazyAttrs 构建的。

话虽如此,我不会实现首次调用时构建的方法,而是通过在首次创建 MBean 或注册 MBean 时简单地构建完整的 MBeanInfo 来实现首次使用前构建。然后只需在每次 getMBeanInfo() 调用时返回预构建的 MBeanInfo。

要在 MBean 注册时执行此操作,请实现 MBeanRegistration接口(interface),并在 postRegister 中构建缓存的 MBeanInfo方法。

关于java - 让子类序列化为父类(super class)的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50768567/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com