2012-10-02 33 views
8

Tengo múltiples servicios que pueden devolver resultados de miles de clases.
Dado que cada servicio CXF contiene un contexto privado casi idéntico de JAXB, causa una enorme pérdida de memoria.
¿Hay alguna manera de crear el contexto JAXB y compartirlo entre los servicios?Reutilizar CXF contexto jaxb entre servicios múltiples

+0

Pregunta interesante, pero no sé la respuesta. –

+1

Esto es para jaxrs, pero puede ser que también funcionará para jaxws: http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-SingleJAXBContextandextrauserclasses –

Respuesta

3

Una posible manera de resolver es mediante la adición de lo siguiente a la configuración del resorte:

<bean class="org.apache.cxf.jaxb.JAXBDataBinding" > 
    <constructor-arg index="0" value="#{GlobalContextBean.context}"/> 
</bean> 

Cuando el valor es sólo una referencia a un grano que tiene el mundial (single) JAXBContext y tiene el siguiente método :

public javax.xml.bind.JAXBContext getContext() {...} 

puede ver más detalles (incluyendo el gurú CXF entradas Daniel Kulp) en el siguiente hilo:
Reuse-JAXB-context-in-jaxws

Después de probarlo, descubrí que la configuración de JAXBDataBinding actual como una instancia global para servicios múltiples no funcionará ya que hay una instrucción "if" en su método de inicialización que se devuelve una vez que el primer servicio configuró el contexto.
Es por eso que terminé extendiendo la clase y recogiendo todas las clases de servicios requeridas y modelos. Después de que finaliza la inicialización de todos los servicios, creo un contexto global con todas las clases requeridas y lo devuelvo a todos los servicios.
Puede usar la siguiente clase.
Después de que todos sus servicios web estén inicializados, llame al método compileGlobalJAXBContext para crear el contexto global. Puede agregar allí otras clases que la aplicación necesite y la init perdida.
No olvide configurar los servicios para que funcionen con este bean.

public class GlobalJAXBDataBinding extends JAXBDataBinding 
{ 
private Set<Class<?>> globalContextClasses; 
private boolean contextBuilt = false; 

public GlobalJAXBDataBinding(Set<Class<?>> classes) { 
    globalContextClasses = new HashSet<>(classes); 
    globalContextClasses.add(CPUUID.class); 
} 

public GlobalJAXBDataBinding() { 
} 

} 

public synchronized void initialize(Service service) { 
    if (contextBuilt) 
     return; 
    super.initialize(service); 
    globalContextClasses.addAll(getContextClasses()); 
    super.setContext(null); 
} 

public void compileGlobalJAXBContext() { 
    if (contextBuilt) return; 
    setContext(JAXBContext.newInstance(globalContextClasses)); 
    contextBuilt *equals* true; 
} 

Por alguna extraña razón el editor no me dejó añadir el signo igual en la última línea de compileGlobalJAXBContext por lo que sólo sustituir la palabra iguales con el signo correspondiente.

+0

Aprecio que esto sea un poco viejo ahora, pero ¿te importaría publicar la clase si aún la tienes? – DarthPablo

+0

@DarthPablo He adjuntado la clase –

+0

Gracias, ¡eso es muy útil! – DarthPablo

Cuestiones relacionadas