Mam wiele usług, które mogą zwracać wyniki z tysięcy klas.
Ponieważ każda usługa CXF zawiera prywatny niemal identyczny kontekst JAXB, powoduje to ogromne marnowanie pamięci.
Czy istnieje sposób na samodzielne utworzenie kontekstu JAXB i udostępnienie go między usługami?Ponowne użycie kontekstu jaxb CXF między wieloma usługami
Odpowiedz
Jednym z możliwych sposobów rozwiązania jest to poprzez dodanie następujących konfiguracji wiosny:
<bean class="org.apache.cxf.jaxb.JAXBDataBinding" >
<constructor-arg index="0" value="#{GlobalContextBean.context}"/>
</bean>
przypadku gdy wartość jest tylko odniesienie do fasoli, która posiada globalną (single) JAXBContext i ma następującą metodę :
public javax.xml.bind.JAXBContext getContext() {...}
można zobaczyć więcej szczegółów (w tym CXF guru wejść Daniel Kulp) w wątku:
Reuse-JAXB-context-in-jaxws
Po przetestowaniu go odkryłem, że ustawienie bieżącego JAXBDataBinding jako instancji globalnej dla wielu usług nie będzie działać, ponieważ w metodzie initialize znajduje się instrukcja "if", która zwraca się, gdy kontekst został ustawiony przez pierwszą usługę.
Dlatego właśnie skończyłem, rozszerzając klasę i zbierając wszystkie wymagane klasy usług i modele. Po zakończeniu wszystkich inicjalizacji usług tworzę globalny kontekst ze wszystkimi wymaganymi klasami i zwracam je do wszystkich usług.
Możesz użyć poniższej klasy.
Po zainicjowaniu wszystkich usług WWW wywołaj metodę compileGlobalJAXBContext w celu utworzenia globalnego kontekstu. Możesz dodać tam inne klasy, których potrzebuje aplikacja, a init pominięto.
Nie zapomnij skonfigurować usług do pracy z tym komponentem 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;
}
Z jakiegoś dziwnego powodu redaktor nie dodam znak równości w ostatniej linii compileGlobalJAXBContext więc po prostu zastąpić słowo równi z odpowiednim znakiem.
Doceniam to jest trochę już stary, ale czy mógłbyś opublikować zajęcia, jeśli nadal je masz? – DarthPablo
@DarthPablo Dołączyłem do klasy –
Dziękuję - to bardzo pomocne! – DarthPablo
Interesujące pytanie, ale nie znam odpowiedzi. –
To jest dla jaxrs, ale może też będzie działać dla jaxws: http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-SingleJAXBContextandextrauserclasses –