具体地说,让我用Spring http-Remoting示例来说明这个问题。
假设我们有这样一个简单接口的实现:
public SearchServiceImpl implements SearchService {
public SearchJdo processSearch(SearchJdo search) {
search.name = "a funky name";
return search;
}
}
SearchJdo本身就是一个简单的POJO。
现在,当我们通过http-emoting(Spring调用远程对象的机制,非常类似于使用序列化的EJB)从客户机调用该方法时,我们将得到:
public class HTTPClient {
public static void main(final String[] arguments) {
final ApplicationContext context = new ClassPathXmlApplicationContext(
"spring-http-client-config.xml");
final SearchService searchService =
(SearchService) context.getBean("searchService");
SearchJdo search = new SearchJdo();
search.name = "myName";
// this method actually returns the same object it gets as an argument
SearchJdo search2 = searchService.processSearch(search);
System.out.println(search == search2); // prints "false"
}
}
问题是,尽管从逻辑的Angular 来看,搜索对象是相同的,但由于序列化,搜索对象是不同的。
问题是,是否有一些技术可以支持或模拟跨VM的对象标识。
3条答案
按热度按时间clj7thdc1#
你说得对--对象同一性不同于逻辑上的相等。
==
进行比较.equals(..)
进行比较因此,覆盖
equals()
方法,一切都会好起来的。记住也要基于相同的字段覆盖hashCode()
。使用您的IDE为您生成这两个方法。(Teracotta VM clustering允许在VM之间共享对象,但这不适合您的情况。)
piah890a2#
IMHO试图在多个VM之间保持对象标识等价性是一个失败的提议。就我所知,语言规范不需要VM来支持这一点,所以如果您真的想要可移植的话,在哪里可以做到这一点是有限的。
我可以问一下,为什么不直接使用您自己提供的唯一ID吗?Java GUID虽然昂贵,但却是可序列化的。
yyyllmsg3#
我曾经这样做过一次,但我不太确定这是不是一个正确的方法:
每个用户都有一个附加到用户对象的用户名、会话ID、角色和登录日期。每次我登录到VM时,系统都会将一个User对象加载到内存中;我还会将User对象返回给应用程序。
如果我需要在应用程序服务器中执行某个操作,那么我会将User对象作为参数发送。如果VM为用户加载了相同的会话ID,那么它将使用存储在VM中的对象来知道分配的角色。否则,应用程序将能够更改用户中的角色,并且它将不安全。
如果应用程序必须更改应用程序服务器,则它会将用户对象发送到新服务器,而新服务器将无法在其记录中找到该用户。
秘密是这样的:会话ID是通过散列用户名、登录日期和在所有服务器之间共享的秘密密码创建的。
一旦新服务器发现会话ID是一致的,它就会从数据库中加载角色作为可靠的信息源。
如果我之前不能写这篇文章,我很抱歉,但希望它能对某人有所帮助。