有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

具体来说,让我用SpringHTTPRemoting示例来说明这个问题

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

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

SearchJdo本身就是一个简单的POJO

现在,当我们通过http远程处理从客户端调用该方法时(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"
    }
}

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

问题是是否有某种技术允许跨VM支持或模拟对象标识


共 (3) 个答案

  1. # 1 楼答案

    IMHO试图在虚拟机之间保持对象标识平等是一个失败的主张。 据我所知,语言规范不需要VM来支持这一点,因此,如果您真的希望具有可移植性,那么您将受到限制

    我可以问一下你为什么不使用你自己提供的一些独特的身份证吗?Java GUI虽然昂贵,但可以序列化

  2. # 2 楼答案

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

    每个用户都将用户名、会话id、角色和登录日期附加到用户对象。每次我登录虚拟机时,系统都会将一个用户对象加载到内存中;我还将用户对象返回到应用程序

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

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

    这里是秘密:会话ID是通过散列用户名、登录日期和所有服务器共享的秘密密码创建的

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

    对不起,如果我以前不能写这篇文章,但希望它能帮助别人

  3. # 3 楼答案

    您说过it-对象标识不同于逻辑相等

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

    所以重写equals()方法,一切都会好起来的。记住也要基于相同的字段重写hashCode()。使用IDE为您生成这两种方法

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