最近在做的项目需要用到memcached,java客户端就选了国产的xmemcached。有个很奇怪的问题,序列化自定义对象是没问题,反序列化对象时就抛出ClassNotFoundException,重新检查这个类,确实存在。
没办法,向google求救,原来,把xmemcached这个包放在tomcat/lib下就会抛出ClassNotFoundException,而放在webapps/[app]/WEB-INF/lib下就正常。估计是不同类加载器的问题。
既然找到了原因,就容易了,打开xmemcached源代码,找到这个类BaseSerializingTranscoder的deserialize方法,用的是jdk提供的ObjectInputStream,又查了jdk文档,只覆盖ObjectInputStream的resolveClass就可以从别的类加载器加载类了。
附上修改后的源代码:
public class CustomerSerializingTranscoder extends SerializingTranscoder { public CustomerSerializingTranscoder() { } @Override protected Object deserialize(byte[] in) { Object rv = null; ByteArrayInputStream bis = null; ObjectInputStream is = null; try { if (in != null) { bis = new ByteArrayInputStream(in); is = new ObjectInputStream(bis) { @Override protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { try { return Thread.currentThread().getContextClassLoader().loadClass(desc.getName()); } catch (ClassNotFoundException e) { return super.resolveClass(desc); } } }; rv = is.readObject(); } } catch (IOException e) { log.error("Caught IOException decoding " + in.length + " bytes of data", e); } catch (ClassNotFoundException e) { log.error("Caught CNFE decoding " + in.length + " bytes of data", e); } finally { if (is != null) { try { is.close(); } catch (IOException e) { } } if (bis != null) { try { bis.close(); } catch (IOException e) { } } } return rv; } }
然后在spring配置文件里指定这个自定义解码器就行了:
<bean id="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder"> ... <property name="transcoder"> <bean class="xxx.CustomerSerializingTranscoder" /> </property> </bean>
这样,不管xmemcached是放在tomcat/lib目录下还是webapps/[app]/WEB-INF/lib目录,都不会抛出ClassNotFoundException了
相关推荐
- **扩展性**:支持自定义序列化和反序列化策略,方便处理各种复杂的数据类型。 ### 2. 使用场景 xmemcached常用于Java Web应用中,尤其是需要高速缓存支持的场景,如: - 用户会话存储 - 数据库查询结果缓存 - ...
总结来说,xmemcached 2.4.5版本相对于2.3.2版本在性能、API、错误处理、序列化和兼容性等方面都有显著提升,为开发者提供了更强大的工具来应对复杂和高并发的分布式环境。在实际项目中,根据业务需求和系统性能,...
Xmemcached支持多种数据类型,包括字符串、字节数组、序列化对象等。 4. **高级功能** - **批量操作**:Xmemcached提供了批量处理键值对的方法,如batchGet()和batchSet(),能显著提高处理效率。 - **事务支持**...
4. **Kryo序列化**: Kryo库提供了一种高效的数据序列化机制,它可以将Java对象转换为字节序列,也可以从字节序列反序列化回对象。Kryo序列化速度快,内存占用少,因此在需要快速存储和检索数据的场景下特别有用,...
相比Java默认的序列化机制,Kryo具有更高的序列化和反序列化速度,且生成的字节流更小,这对于网络传输和内存占用非常重要。 要在Tomcat 8.0中实现Memcached session共享,你需要以下步骤: 1. **安装Memcached...
Kryo是一个高效的序列化库,常与Memcached结合使用,因为它可以显著减少序列化和反序列化的时间。如果压缩包中包含kryo相关的jar(如kryo.jar),那么这表明可以使用Kryo进行数据序列化,以提升缓存效率。 4. **...
4. **处理序列化与反序列化**:由于session数据需要在网络间传输,所以必须能够被序列化和反序列化。需要确保应用中的session属性类实现了Serializable接口。 5. **测试与优化**:完成配置后,进行测试,确保在多台...
9. **序列化与反序列化**:Memcache不处理复杂数据类型,如对象。因此,需要使用序列化技术(如JSON或Java序列化)将对象转换为字节流,再存储到Memcache。反之,读取时反序列化回原对象。 10. **最佳实践**:为了...
6. **序列化与反序列化**:由于Memcached只支持基本类型和字符串,我们需要对Java对象进行序列化和反序列化。可以选择JSON、protobuf或其他序列化框架。 7. **扩展性**:设计良好的接口,方便后续添加新的功能,如...
- **transcoder**:数据转换器,负责对象的序列化和反序列化。 - **bufferAllocator**:缓冲区分配器,管理网络通信中的内存分配。 通过这种方式,Spring开发者可以方便地在Spring配置文件中管理memcached客户端,...
比如,`kryo序列化`可能指的是Kryo库,它是一个快速、高效的对象图形序列化框架,可用于将Java对象转换为字节流,从而更有效地存储在memcached中。 2. **Tomcat Session Manager**:Tomcat提供了一种名为`...
- **扩展性**:支持自定义序列化和反序列化策略,适应不同的数据类型和业务需求。 - **容错机制**:具备基本的故障检测和恢复功能,当连接丢失时,可以自动重连。 **使用Java Memcached客户端** 无论选择哪个...
1. **序列化和反序列化**:由于`Memcached`存储的是原始字节,所以需要定义合适的序列化和反序列化策略,以确保对象在存取时的正确性。 2. **缓存策略**:设置合理的缓存有效期和更新策略,例如基于时间的过期、LRU...
还可以配置缓存的命名空间,以及序列化和反序列化的策略。 6. **缓存操作**:通过XMemcached的API,可以在应用中进行添加(set)、获取(get)、删除(delete)等操作。还可以设置过期时间,实现自动失效的缓存管理...
- **序列化与反序列化**:由于Memcached只接受字节流,Java对象需要经过序列化才能存储,反序列化时再恢复为对象。 - **并发控制**:对于多线程环境,可能需要使用锁或其他并发控制机制,确保数据的一致性和完整性...
5. **序列化与反序列化**:由于Memcached处理的是字节流,所以非基本类型的数据需要序列化。spymemcached提供了一些内置的序列化器,如`BinarySerialization`,但你也可以自定义序列化器。 6. **并发与性能**:...
xmemcached提供了丰富的功能,包括连接池管理、自动故障转移、序列化和反序列化策略等,使得Java应用能更有效地利用Memcached的缓存能力。 总结来说,这三个文件共同构成了一个Memcached的开发和使用环境:libevent...
- **命令序列化与反序列化**:因为Memcached处理的是键值对,所以数据需要被序列化成字节流,然后在客户端和服务器之间传输。这可能涉及到JSON、protobuf或其他序列化格式。 - **Key-Value操作**:基本的get、set、...
6. 当用户请求到来时,根据会话ID从Memcached中获取并反序列化会话数据。 总结一下,"Memcached负载均衡Jar包大全"中包含的jar文件主要用于Java应用与Memcached服务器之间的通信,实现会话数据的分布式存储和共享。...