6
votes

Sécurité du fil lors de l'utilisation de SpringServiceTemplate et JAXB2MARSHALLER

J'utilise Spring WebserviceTemplate en tant que client de service Web Programmatiquement, sans instanciation d'un conteneur à ressort. J'utilise Jaxb2marshaller pour le maréchaling / la mixte. Dans ma candidature, je crée une seule instance de SaajsoapMessageAfactory et une instance de Jaxb2marshaller. Je crée également une seule instance de WebServiceTemplate et attribuez les instances précédemment créées de SaajsoapMessagealageFactory et Jaxb2marshaller.

Le WebServiceTemplate que j'ai créé est utilisé dans une manière multi-filetée, c'est-à-dire que. Plusieurs threads peuvent appeler des marshalsendandreceive en même temps. Ma question est: mon fil de configuration est-il sûr? Je suis préoccupé par le Jaxb2marshaller. Le Javadoc dit que Jaxb2marshallers ne traite pas nécessairement de sécurité. Comment puis-je utiliser le JAXB2MARSHALLER dans un fil de fil sans réinitialiser le contexte JAXB?

Afrett: regarder l'exemple de configuration Spring-WS dans La référence de printemps me conduit à croire que le jaxb2marshaller est en sécurité, mais le Javadoc semble contredire cela.


0 commentaires

3 Réponses :


0
votes

Créer plusieurs JAXB2MARSHALLER (disons cinq), mettez-les dans une piscine (utilisez linkedblockingQueue ). Lorsque vous créez un fil, passez la file d'attente.

Lorsqu'un fil a besoin d'un, prend () un de la file d'attente / piscine. Lorsque la piscine est vide, les threads bloqueront cet appel.

Lorsqu'un thread est effectué à l'aide du jaxb2marshaller , Met () retour dans la file d'attente afin que d'autres threads puissent l'utiliser.

Si vous trouvez que les threads bloquent trop souvent pour un maréhalleur, ajoutez plus à la file d'attente (voir la première étape). De cette façon, vous pouvez facilement former la piscine (ou même le rendre configurable). La file d'attente les distribuera automatiquement automatiquement.


1 commentaires

Cela fonctionnera et l'idée de piscine est largement utilisée avec des objets lourds à instancier, mais vous devrez ensuite gérer l'état des objets et ainsi de suite, tel est fait dans le pool de connexion. Mais Marshaller n'est pas un objet lourd d'instancier. Jaxbcontext est.



7
votes

Le Javadoc pour Jaxb2marshaller ne fait aucune mention de fil-sécurité d'une manière ou d'une autre, donc je ne sais pas pourquoi vous pensez que ce n'est pas le cas. Si ce n'était pas très sûr, le Javadoc dirait que très clairement.

Votre configuration de WebServiceTemplate , SAAJSOAAPMessageFactory et jaxb2marshaller singletons est parfaitement parfait et entièrement sur le thread-coffre-fort.


7 commentaires

La définition du Createmarshaller () [ static.springsource.org/spring-ws/sites/1.5/apidocs/org/... méthode a semé la graine du doute dans mon esprit. Il dit que "les marshallers Jaxb ne sont pas nécessairement en sécurité." Je sais qu'ils parlent de javax.xml.bind.marshaller mais je ne sais pas comment Jaxb2marshaller utilise cette classe (ou implémentations de cette interface).


@neesh: ah, ok. Ceci est vrai, Marshaller et MODARSHALLER ne sont pas thread-coffre-fort, c'est pourquoi Spring-WS ne les partage pas entre les threads. Il s'agit d'une utilisation correcte de l'API JAXB.


J'ai eu ces problèmes il y a quelque temps où j'avais besoin de lamaturer manuellement à l'aide d'un marshaller singleton dans un flux multi-fileté et il est certainement mal conduit jusqu'à ce que je me suis assuré que chaque fil avait sa propre instance.


Pourquoi cette réponse choisie est-elle correcte ?? est-ce correct??


Spring Jaxb2Marshaller contient un jaxbcontext Singleton et crée un Jaxb2marshaller pour chaque opération de marshalling comme suggéré par JAXB. Donc, le printemps jaxb2marshaller a une mise en œuvre correcte de la sécurité du fil.


Jaxb2marshaller fonctionne bien mais est mal nommé; Il devrait probablement être appelé quelque chose comme Jaxb2Marshallerwrapper pour indiquer que ce n'est pas un marshallateur Jaxb.


Correct, laissez-moi ajouter qu'un jaxb2marsaller implémente l'interface org.springframework.oxm.marshaller. L'ambiguït provient donc du nom du conflit de cette interface avec le javax.xml.bind.marshaller créé sur chaque appel à marshal ()



2
votes

La classe org.springframework.oxm.jaxb.jaxb2marshaller est le fil sûr, car il crée pour chaque événement Marshalling Nouvelle instance de javax.xml.bind.marshaller, voir le code source d'origine à partir du printemps 5.2.6:

@Override
public void marshal(Object graph, Result result, @Nullable MimeContainer mimeContainer) throws XmlMappingException {
    try {
        Marshaller marshaller = createMarshaller();
        if (this.mtomEnabled && mimeContainer != null) {
            marshaller.setAttachmentMarshaller(new Jaxb2AttachmentMarshaller(mimeContainer));
        }
        if (StaxUtils.isStaxResult(result)) {
            marshalStaxResult(marshaller, graph, result);
        }
        else {
            marshaller.marshal(graph, result);
        }
    }
    catch (JAXBException ex) {
        throw convertJaxbException(ex);
    }
}

/**
 * Return a newly created JAXB marshaller.
 * <p>Note: JAXB marshallers are not necessarily thread-safe.
 * This method is public as of 5.2.
 * @since 5.2
 * @see #createUnmarshaller()
 */
public Marshaller createMarshaller() {
    try {
        Marshaller marshaller = getJaxbContext().createMarshaller();
        initJaxbMarshaller(marshaller);
        return marshaller;
    }
    catch (JAXBException ex) {
        throw convertJaxbException(ex);
    }
}


0 commentaires