首先,我对奇怪的标题表示歉意。我真的不知道该怎么称呼。
我们有一个“ Factory”类,其中包含针对所生成的Bean中存在的每个属性的方法。 Factory类的每个方法均以与包含该属性的特定类相关的方式命名,并旨在创建该属性的JAXBElement。不幸的是,该类也是自动生成的。看起来像这样:
public class Factory {
private final static QName _MyClassImpl1Attribute1Name_QNAME = new QName("urn:some.urn", "attribute1Name");
private final static QName _MyClassImpl1Attribute2Name_QNAME = new QName("urn:some.urn", "attribute2Name");
private final static QName _MyClassImpl2Attribute1Name_QNAME = new QName("urn:some.urn", "attribute1Name");
private final static QName _MyClassImpl2Attribute2Name_QNAME = new QName("urn:some.urn", "attribute2Name");
/**
* Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}}
*
*/
@XmlElementDecl(namespace = "urn:some.urn", name = "attribute1Name", scope = MyClassImpl1.class)
public JAXBElement<String> createMyClassImpl1Attribute1Name(String value) {
return new JAXBElement<String>(_MyClassImpl1Attribute1Name_QNAME, String.class, MyClassImpl1.class, value);
}
/**
* Create an instance of {@link JAXBElement }{@code <}{@link Boolean}{@code >}}
*
*/
@XmlElementDecl(namespace = "urn:some.urn", name = "attribute2Name", scope = MyClassImpl1.class)
public JAXBElement<Boolean> createMyClassImpl1Attribute2Name(Boolean value) {
return new JAXBElement<Boolean>(_MyClassImpl1Attribute2Name_QNAME, Boolean.class, MyClassImpl1.class, value);
}
/**
* Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}}
*
*/
@XmlElementDecl(namespace = "urn:some.urn", name = "attribute1Name", scope = MyClassImpl2.class)
public JAXBElement<String> createMyClassImpl2Attribute1Name(String value) {
return new JAXBElement<String>(_MyClassImpl2Attribute1Name_QNAME, String.class, MyClassImpl2.class, value);
}
/**
* Create an instance of {@link JAXBElement }{@code <}{@link Boolean}{@code >}}
*
*/
@XmlElementDecl(namespace = "urn:some.urn", name = "attribute2Name", scope = MyClassImpl2.class)
public JAXBElement<Boolean> createMyClassImpl2Attribute2Name(Boolean value) {
return new JAXBElement<Boolean>(_MyClassImpl2Attribute2Name_QNAME, Boolean.class, MyClassImpl2.class, value);
}
}
这里的问题是每个方法名称都与一个类名称匹配。没有说“创建接口的属性”的方法,这将允许一种方法适用于该接口的所有实现。同样,无法修改Factory。实际上,唯一可以修改的类是该接口:
public interface MyInterface {
JAXBElement<String> getAttribute1Name;
void setAttribute1Name(String attribute1Value);
JAXBElement<Boolean> getAttribute2Name;
void setAttribute2Name(Boolean attribute2Value);
}
这里是生成的2个类(留下了一些在这里不相关的xml标记)
public class MyClassImpl1 implements MyInterface {
private String attribute1Name;
private Boolean attribute2Name;
public JAXBElement<String> getAttribute1Name() {
return attribute1Name;
}
public void setAttribute1Name(JAXBElement<String> value) {
this.attribute2Name = value;
}
public JAXBElement<Boolean> getAttribute2Name() {
return attribute2Name;
}
public void setAttribute2Name(JAXBElement<Boolean> value) {
this.attribute2Name = value;
}
}
public class MyClassImpl2 implements MyInterface {
private String attribute1Name;
private Boolean attribute2Name;
public JAXBElement<String> getAttribute1Name() {
return attribute1Name;
}
public void setAttribute1Name(JAXBElement<String> value) {
this.attribute2Name = value;
}
public JAXBElement<Boolean> getAttribute2Name() {
return attribute2Name;
}
public void setAttribute2Name(JAXBElement<Boolean> value) {
this.attribute2Name = value;
}
}
当我对设置器进行接口调用时会发生问题,因为工厂不知道要调用哪种方法(类的特定名称)。
public class AnotherClass {
public void anotherMethod(MyInterface myInterface) {
Factory factory = new Factory();
String value1 = "Some String Value";
Boolean value2 = true;
myInterface.setAttribute1Name(factory.<I need correct method here>(value1));
myInterface.setAttribute2Name(factory.<I need correct method here>(value2));
}
}
我也许可以通过反射来做到这一点,但是我对此不太满意,坦率地说,我不喜欢这样做。但这可能是可能起作用的。 将其放在MyInterface上:
default JAXBElement getClassImplJaxbElement(Object attributeValue, String attributeToSet, Factory factory) {
String factoryMethodName = "create" + this.getClass().getName() + attributeToSet;
Expression attributeGetter = new Expression(factory, factoryMethodName, new Object[]{attributeValue});
try {
attributeGetter.execute();
return (JAXBElement) attributeGetter.getValue();
} catch (Exception e) {
throw new MyRuntimeException(String.format("Failed to create JAXBElement for attribute '%s' and value '%s'.", attributeToSet, attributeValue), e);
}
}
尤其令人讨厌的是,我必须在要在接口上调用setter的任何地方调用该新方法,这意味着每次反射都很慢。有人知道这样做的方法吗?同样,不能修改ClassImpls也不能修改Factory。
通过.xsd文件和maven插件maven-jaxb22-plugin生成类。通过添加jaxb2-basics插件,我可以生成实现接口的类。