RopResponseMarshaller的实现类包括以下两个:
- JacksonJsonRopResponseMarshaller:内部使用org.codehaus.jackson.map.ObjectMapper进行JSON序列化
- JaxbXmlRopResponseMarshaller:内部使用javax.xml.bind.Marshaller进行XML序列化
org.codehaus.jackson.map.ObjectMapper是线程安全的(参见:
http://wiki.fasterxml.com/JacksonFAQThreadSafety),而javax.xml.bind.Marshaller是非线程安全的。原来的Rop对ObjectMapper和Marshaller都采用了单实例的方式,因此存在线程安全的问题。
关于javax.xml.bind.Marshaller非线程安全的说明参见:
http://jaxb.java.net/guide/Performance_and_thread_safety.html
不但javax.xml.bind.Marshaller是非线程安全的,Spring OXM的Marshaller也是非线程安全的,参见其javadoc的说明:
引用
createMarshaller
protected Marshaller createMarshaller()
Return a newly created JAXB marshaller.
JAXB marshallers are not necessarily thread safe.
原来的JaxbXmlRopResponseMarshaller:
- public class JaxbXmlRopResponseMarshaller implements RopResponseMarshaller {
-
- private static Map<Class, Marshaller> marshallerMap = new HashMap<Class, Marshaller>();
-
- public void marshaller(RopResponse response, OutputStream outputStream) {
- try {
- Marshaller m = getMarshaller(response);
- m.marshal(response, outputStream);
- } catch (JAXBException e) {
- throw new RopException(e);
- }
- }
-
- private Marshaller getMarshaller(RopResponse response) throws JAXBException {
- if (!marshallerMap.containsKey(response.getClass())) {
- JAXBContext context = JAXBContext.newInstance(response.getClass());
- Marshaller marshaller = context.createMarshaller();
- marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- marshaller.setProperty(Marshaller.);
- marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
- marshallerMap.put(response.getClass(), marshaller);
- }
- return marshallerMap.get(response.getClass());
- }
- }
更改为:
- public class JaxbXmlRopResponseMarshaller implements RopResponseMarshaller {
-
- private static Map<Class, JAXBContext> jaxbContextHashMap = new ConcurrentHashMap<Class, JAXBContext>();
-
- public void marshaller(RopResponse response, OutputStream outputStream) {
- try {
- Marshaller m = buildMarshaller(response);
- m.marshal(response, outputStream);
- } catch (JAXBException e) {
- throw new RopException(e);
- }
- }
-
-
- public Marshaller buildMarshaller(RopResponse response) throws JAXBException {
- if (!jaxbContextHashMap.containsKey(response.getClass())) {
- JAXBContext context = JAXBContext.newInstance(response.getClass());
- jaxbContextHashMap.put(response.getClass(), context);
- }
- JAXBContext context = jaxbContextHashMap.get(response.getClass());
- Marshaller marshaller = context.createMarshaller();
- marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
- return marshaller;
- }
- }
其实,根据测试创建Marshaller的时间很短,只有1毫秒左右,而真正慢的是创建JAXBContext,大家100毫秒左右。所以,这样改后,对Rop序列化的性能不会有什么影响,因为JAXBContext是共享的。
已经同步到git中。