如何跨不同的VM保留对象标识

时间:2010-06-08 00:39:35

标签: java spring serialization remoting identity

具体来说,让我用Spring http-remoting示例说明问题。

假设我们有一个简单接口的实现:

public SearchServiceImpl implements SearchService {
    public SearchJdo processSearch(SearchJdo search) {
        search.name = "a funky name";
        return search;
    }
}

SearchJdo本身就是一个简单的POJO。

现在,当我们通过 http-remoting (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"
    }
}

问题在于搜索对象因序列化而不同,尽管从逻辑角度来看它们是相同的。

问题是是否存在一些允许跨虚拟机支持或模拟对象身份的技术。

3 个答案:

答案 0 :(得分:1)

IMHO试图在虚拟机中保持对象身份的平等是一个失败的主张。 据我所知,语言规范不需要VM来支持它,因此如果您真的想要移植,那么您可能会受到限制。

请问您为什么不使用自己提供的一些独特ID? Java GUID虽然很昂贵,但可以序列化。

答案 1 :(得分:1)

你说过 - 对象身份与逻辑平等不同。

  • 将对象标识与==
  • 进行比较
  • 逻辑相等与.equals(..)
  • 进行比较

所以覆盖equals()方法,一切都会好的。请记住,根据相同的字段覆盖hashCode()。使用IDE为您生成这两种方法。

Teracotta VM clustering允许在VM之间共享对象,但这不适合您的情况。)

答案 2 :(得分:0)

我这样做了一次,但我不确定这是否是正确的方法:

每个用户都有一个用户名,会话ID,角色和附加到用户对象的登录日期。每次登录VM时,系统都会将User对象加载到内存中;我还会将用户对象返回给应用程序。

如果我需要在应用程序服务器中执行操作,那么我会将用户对象作为参数发送。如果VM使User具有相同的会话ID,则它将使用VM中存储的对象来了解分配的角色。否则,应用程序将能够更改用户中的角色,并且不安全。

如果应用程序必须更改应用程序服务器,则它会将用户对象发送到新服务器,新服务器将无法在其记录中找到用户。

这里是秘密:会话ID被创建哈希用户名,登录日期和所有服务器之间共享的密码。

一旦新服务器发现会话ID一致,那么它将从数据库加载角色作为可靠的信息来源。

很抱歉,如果我以前不能写这个,但希望对某人有帮助。