Spring 中的 RMIPRoxyFactoryBean 工厂?

发布于 2024-08-02 05:13:49 字数 661 浏览 3 评论 0原文

我目前正在使用 Spring RmiProxyFactoryBean 来访问远程服务。由于需求发生了变化,我需要在运行时指定不同的主机 - 可以有很多 - ,但 remoteServiceInterfaceremoteServiceUrl 的非主机组件仍然存在相同。

从概念上讲,我会看到一个类似于以下内容的 bean 定义:

<bean class="org.springframework.remoting.rmi.RmiProxyFactoryBeanFactory">
     <property name="serviceInterface" value="xxx"/>
     <property name="serviceUrl" value="rmi://#{HOST}:1099/ServiceUrl"/>
</bean>

它公开了

Object getServiceFor(String hostName);

Spring 是否有这样的服务可用?或者,您是否看到另一种方法?


请注意,主机列表在编译或启动时是未知的,因此我无法在 xml 文件中生成它。

I'm currently using a Spring RmiProxyFactoryBean to access remote services. Since requirements have changed, I need to specify at runtime a different host - there can be many of them - , but the remoteServiceInterface and the non-host components of the remoteServiceUrl remain the same.

Conceptually speaking, I'd see a bean definition similar to:

<bean class="org.springframework.remoting.rmi.RmiProxyFactoryBeanFactory">
     <property name="serviceInterface" value="xxx"/>
     <property name="serviceUrl" value="rmi://#{HOST}:1099/ServiceUrl"/>
</bean>

which exposes a

Object getServiceFor(String hostName);

Is there such a service available with Spring? Alternatively, do you see another way of doing this?


Please note that the host list will not be known at compile or startup time, so I can't generate it in the xml file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜心小果奶 2024-08-09 05:13:49

如果您查看 RmiProxyFactoryBean 的源代码,您会发现它是 RmiClientInterceptor 的一个非常薄的子类,而 RmiClientInterceptor 只是一个标准的 AOP MethodInterceptor。这对我来说意味着您可以编写一个自定义类来实现您想要的 getServiceFor(hostname) 方法,并且该方法可以以与 RmiProxyFactoryBean 类似的方式使用 Spring ProxyFactory 来生成运行时代理对于您的特定主机。

例如:

public Object getProxyFor(String hostName) {
    RmiClientInterceptor rmiClientInterceptor = new RmiClientInterceptor();
    rmiClientInterceptor.setServiceUrl(String.format("rmi://%s:1099/ServiceUrl", hostName));
    rmiClientInterceptor.setServiceInterface(rmiServiceInterface);
    rmiClientInterceptor.afterPropertiesSet();

    return new ProxyFactory(proxyInterface, rmiClientInterceptor).getProxy();
}

其中 rmiServiceInterfaceproxyInterface 是您定义的类型。

If you look at the source for RmiProxyFactoryBean, you can see that it's a very thin subclass of RmiClientInterceptor, which is just a standard AOP MethodInterceptor. This suggests to me that you could write a custom class which implements your desired getServiceFor(hostname) method, and this method could use a Spring ProxyFactory in a similar way to RmiProxyFactoryBean, to generate a run-time proxy for your specific host.

For example:

public Object getProxyFor(String hostName) {
    RmiClientInterceptor rmiClientInterceptor = new RmiClientInterceptor();
    rmiClientInterceptor.setServiceUrl(String.format("rmi://%s:1099/ServiceUrl", hostName));
    rmiClientInterceptor.setServiceInterface(rmiServiceInterface);
    rmiClientInterceptor.afterPropertiesSet();

    return new ProxyFactory(proxyInterface, rmiClientInterceptor).getProxy();
}

Where rmiServiceInterface and proxyInterface are types defined by you.

絕版丫頭 2024-08-09 05:13:49

我最终实现了类似的东西:

public class RmiServiceFactory implements BeanClassLoaderAware {
  public Service getServiceForHost(String hostName) {
    factory = new RmiProxyFactoryBean();
    factory.setLookupStubOnStartup(false);
    factory.setRefreshStubOnConnectFailure(true);
    factory.setServiceInterface(Service.class);
    factory.setServiceUrl(String.format(_serviceUrlFormat, hostName));
    if (_classLoader != null)
        factory.setBeanClassLoader(_classLoader);

    factory.afterPropertiesSet();
  }
}

当然,涉及一些健全性检查和缓存,但我忽略了它们。

I ended up implemeting something similar to:

public class RmiServiceFactory implements BeanClassLoaderAware {
  public Service getServiceForHost(String hostName) {
    factory = new RmiProxyFactoryBean();
    factory.setLookupStubOnStartup(false);
    factory.setRefreshStubOnConnectFailure(true);
    factory.setServiceInterface(Service.class);
    factory.setServiceUrl(String.format(_serviceUrlFormat, hostName));
    if (_classLoader != null)
        factory.setBeanClassLoader(_classLoader);

    factory.afterPropertiesSet();
  }
}

Of course, there is some sanity checking and caching involved, but I've ommited them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文