Bien que la la fonctionnalité demandée ne semble pas être présent dans JAXB, je réussi à réaliser quelque chose qui va dans la bonne direction:
- J'utilise
@PostConstruct
annotation de JSR-305
(il est juste une annotation nacked, aucune fonctionnalité n'est fournie par le JSR)
- J'ajoute unmasrshaller-listener au unmarshaller, qui est invoqué par JAXB chaque fois qu'un objet est unmarshalled.
- J'inspectent cet objet en utilisant la réflexion Java et la recherche de l'annotation
@PostConstruct
sur une méthode
- I exécuter la méthode
Testé. Travaux.
Voici le code. Désolé, je suis en utilisant une API de réflexion externe pour obtenir toutes les méthodes, mais je pense que l'idée est compréhensible:
mise en œuvre
JAXBContext context = // create the context with desired classes
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setListener(new Unmarshaller.Listener() {
@Override
public void afterUnmarshal(Object object, Object arg1) {
System.out.println("unmarshalling finished on: " + object);
Class<?> type = object.getClass();
Method postConstructMethod = null;
for (Method m : ReflectionUtils.getAllMethods(type)) {
if (m.getAnnotation(PostConstruct.class) != null) {
if (postConstructMethod != null) {
throw new IllegalStateException(
"@PostConstruct used multiple times");
}
postConstructMethod = m;
}
}
if (postConstructMethod != null) {
System.out.println("invoking post construct: "
+ postConstructMethod.getName() + "()");
if (!Modifier.isFinal(postConstructMethod.getModifiers())) {
throw new IllegalArgumentException("post construct method ["
+ postConstructMethod.getName() + "] must be final");
}
try {
postConstructMethod.setAccessible(true); // thanks to skaffman
postConstructMethod.invoke(object);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}
}
});
EDIT
Ajout d'un chèque de @PostConstruct
méthode -annotated, à assurez-vous qu'il est définitif.
Pensez-vous que c'est une restriction utile?
Utilisation
Voici comment le concept pourrait être utilisé.
@XmlAccessorType(XmlAccessType.NONE)
public abstract class AbstractKeywordWithProps
extends KeywordCommand {
@XmlAnyElement
protected final List<Element> allElements = new LinkedList<Element>();
public AbstractKeywordWithProps() {
}
@PostConstruct
public final void postConstruct() {
// now, that "allElements" were successfully initialized,
// do something very important with them ;)
}
}
// further classes can be derived from this one. postConstruct still works!
a déposé une demande de fonctionnalité
https://jaxb.dev.java.net/issues/show_bug.cgi?id=698
Grande question, mais je ne pense pas qu'il y ait quelque chose comme ça. Il pourrait et devrait être, cependant, je vous encourage à enregistrer une demande de fonctionnalité sur http://jaxb.dev.java.net – skaffman
Excellent :) https://jaxb.dev.java.net/issues/show_bug.cgi ? id = 698 – skaffman
Regardez-vous la liste de diffusion JAXB pour les bugs? ;) Et comment ça se fait, qu'il a déjà 10 votes? –