Java MOXy/JAXB“原型模式”-接口继承
我正在尝试使用MOXy/jaxb2.5.0实现四人帮原型模式的一个版本。我希望能够指定项目列表,其中一些项目基于其他项目,即从其他实例复制其数据。为了可重用性,我想创建一个接口,任何可原型对象都应该实现该接口,该接口将为支持该模式所需的属性提供注释Java MOXy/JAXB“原型模式”-接口继承,java,inheritance,interface,jaxb,moxy,Java,Inheritance,Interface,Jaxb,Moxy,我正在尝试使用MOXy/jaxb2.5.0实现四人帮原型模式的一个版本。我希望能够指定项目列表,其中一些项目基于其他项目,即从其他实例复制其数据。为了可重用性,我想创建一个接口,任何可原型对象都应该实现该接口,该接口将为支持该模式所需的属性提供注释 @XmlRootElement(name="IPrototype") public interface IPrototype { /** * Acts as a "copy constructor" */ @Xml
@XmlRootElement(name="IPrototype")
public interface IPrototype
{
/**
* Acts as a "copy constructor"
*/
@XmlAttribute(name="prototype")
@XmlIDREF
public void setPrototype(IPrototype prototype);
@XmlAttribute(name="id")
@XmlID
public void setId(String id);
public String getId();
}
理想情况下,实现对象应该是这样的,甚至不必为从接口实现的方法进行注释:
@XmlRootElement(name="Item")
public class Item implements IPrototype
{
private String m_id = null;
private String m_data = null;
public Item()
{
}
/**
* Never called
*/
@Override
public void setPrototype(IPrototype prototype)
{
m_data = ((Item)prototype).getData();
}
@Override
public void setId(String id)
{
m_id = id;
}
@Override
public String getId()
{
return m_id;
}
@XmlAttribute(name="data")
public void setData(String data)
{
m_data = data;
}
public String getData()
{
return m_data;
}
}
XML看起来像:
<Wrapper>
<Item id="Item1" data="stuff and things" />
<Item id="Item2" prototype="Item1" />
</Wrapper>
其中包装器定义为:
@XmlRootElement(name="Wrapper")
public class Wrapper
{
@XmlElementRef
private ArrayList<Item> m_items = null;
}
如果它按照我想要的方式工作,我将得到一个包含两个元素的列表,两个元素都是Item类型,包含相同的数据。但是,MOXy似乎看不到接口上的注释,我得到了一个列表,其中有两个项没有设置XmlID,并且从未调用setPrototype。唯一的解决方案似乎是在Item类中注释setPrototype和setId方法,但这似乎需要将setPrototype的参数类型从IPrototype更改为Item,以便MOXy在正确的类中查找XmlID。不幸的是,这破坏了继承的接口
如果我改为将列表类型改为IPrototype,希望这能让MOXy看到它的注释,那么我会得到相同的行为-null ID,setPrototype从未调用过。无论如何,这并不是我真正想要的,我希望能够约束特定列表中可能包含哪些子类型
我不确定我对接口注释应该如何工作有正确的期望,也许这就是我错误的根源
你有什么想法可以让它工作吗?提前感谢,
史蒂夫
更新:如果我注释Item类,而不更改setPrototype的方法签名(我想我可以接受),我会得到一个包含两个项的列表,正确设置了XmlID,但是setPrototype仍然没有被调用。似乎MOXy正在寻找具有相同XmlID的IPrototype实例,而不是项实例
更新2:而且,如果我将IPrototype转换成一个抽象类,那么一切都可以完美地工作。然而,考虑到Java的单继承模型,这对于旨在补充多继承层次结构的框架对象来说太有限了。所以仍然卡住了。通过注释项的属性并使用泛型声明setPrototype,我得到了一个可以接受的版本。这是IPrototype中的声明:
public <T> void setPrototype(T prototype);
下面是它在项目中的实现:
@XmlAttribute(name="prototype")
@XmlIDREF
@Override
public <T> void setPrototype(T prototype)
{
m_data = ((Item)prototype).getData();
}
它可以工作,但我并不特别喜欢重新注释子类。关于这一点,我提出了一个单独的问题,因为在我看来,界面注释的工作方式并不是这样的:
您可以使用MOXy的外部绑定文档覆盖实现类的超类,即从对象到接口IPrototype的项。这将允许您从接口继承映射 有关完整示例,请参见:
但是如果我试图用一个有界类型参数:public void setPrototypeT prototype来声明这个方法,它就不起作用了。我遇到一个异常,抱怨IPrototype没有用@XmlID注释的属性。如果我对这些方法进行注释,则不会调用setPrototype。现在是如此无界。