【Spring】几种RPC模型的使用与比较——JAX-WS

看来使用web service是不可避免的。
我曾对这个有些抵触,因为他给我印象总是麻烦+慢(后来虽然方便了许多,但还是很慢)。
然后再去搜索"advantages of web service"什么的试着再让自己接受他。
简单记录一下如何用Spring导出Endpoint。

假设我想在有一个Spring应用,我需要把一个Pojo或者一部分方法导出为Web Service。
但这会有一个问题——Endpoint的生命周期是由JAX-WS runtime来管理(The lifecycle of such an endpoint instance will be managed by the JAX-WS runtime),Spring context中的Bean无法autowire到Endpoint中,而我要导出的那些东东都用到了Spring管理的Bean。

对此,我们有两个解决方法:
·org.springframework.web.context.support.SpringBeanAutowiringSupport
·JaxWsServiceExporter

我上面括号中的那段话是引用的SpringBeanAutowiringSupport的javaDoc。
使用该类的典型案例就是bean注入到JAX-WS endpoint类中(人家注释上写的),任何一个生命周期不是由Spring来管理的场景都可以用到他。
而我们只需要继承这个类,也就是说创建一个实例时会调用父类的无参构造方法,我们来看看他的构造方法:

/**
 * This constructor performs injection on this instance,
 * based on the current web application context.
 * <p>Intended for use as a base class.
 * @see #processInjectionBasedOnCurrentContext
 */
public SpringBeanAutowiringSupport() {
    processInjectionBasedOnCurrentContext(this);
}
/**
 * Process {@code @Autowired} injection for the given target object,
 * based on the current web application context.
 * <p>Intended for use as a delegate.
 * @param target the target object to process
 * @see org.springframework.web.context.ContextLoader#getCurrentWebApplicationContext()
 */
public static void processInjectionBasedOnCurrentContext(Object target) {
    Assert.notNull(target, "Target object must not be null");
    WebApplicationContext cc = ContextLoader.getCurrentWebApplicationContext();
    if (cc != null) {
        AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
        bpp.setBeanFactory(cc.getAutowireCapableBeanFactory());
        bpp.processInjection(target);
    }
    else {
        if (logger.isDebugEnabled()) {
            logger.debug("Current WebApplicationContext is not available for processing of " +
                    ClassUtils.getShortName(target.getClass()) + ": " +
                    "Make sure this class gets constructed in a Spring web application. Proceeding without injection.");
        }
    }
}

那就试试看:

@Service
@WebService(serviceName="testMyService")
public class MyServiceEndpoint extends SpringBeanAutowiringSupport{
    @Autowired
    MyService myService;

    @WebMethod
    public String sayHiFarAway(String name){
        return myService.sayHiTo(name);
    }
}

接着发布一下:

ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:applicationContext*.xml");
Endpoint.publish("http://localhost:8080/myservices", (MyServiceEndpoint)context.getBean(MyServiceEndpoint.class));

调用:

QName q = new QName("http://endpoint.king.pac/","MyServiceEndpointPort");
MyClientService client = service.getPort(q,MyClientService.class);
System.out.println(client.sayHiFarAway("King"));

写一个EndPoint还要继承和业务无关的类,让人不爽...而且发布和调用都麻烦。
那试试SimpleJaxWsServiceExporter,只需要简单的配置就可以导出一个EndPoint。
但是他也有需要注意的地方,引用一下该类的javaDoc:
Note that this exporter will only work if the JAX-WS runtime actually supports publishing with an address argument, i.e. if the JAX-WS runtime ships an internal HTTP server. This is the case with the JAX-WS runtime that‘s inclued in Sun‘s JDK 1.6 but not with the standalone JAX-WS 2.1 RI.

SimpleJaxWsServiceExporter会自动detect所有被WebService注解的类,因此只需要在配置中声明即可;此时Endpoint地址直接使用默认的localhost:8080:

<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter" />

接着改善一下客户端的调用,使用JaxWsPortProxyFactoryBean:

<bean id="clientSide" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean"
    p:wsdlDocumentUrl="http://localhost:8080/testMyService?wsdl"
    p:serviceName="testMyService"
    p:portName="MyServiceEndpointPort"
    p:serviceInterface="pac.king.endpoint.MyClientService"
    p:namespaceUri="http://endpoint.king.pac/"
/>

这样就可以像使用普通bean一样使用service了:

MyClientService client = (MyClientService)context.getBean("clientSide");
System.out.println(client.sayHiFarAway("King"));

用起来方便了不少,但仍然无法改变一个事实:
Web service requests are larger than requests encoded with a binary protocol.
还有就是http/https的问题。
如果使用不当,我可能需要多做些工作去处理HTTP做不来的事情,而这时候RMI又非常适合。

【Spring】几种RPC模型的使用与比较——JAX-WS

时间: 2024-10-08 11:13:25

【Spring】几种RPC模型的使用与比较——JAX-WS的相关文章

Spring - 几种RPC模型的使用与比较

Spring中,用JMS搞RPC时会用到: org.springframework.jms.remoting.JmsInvokerServiceExporter org.springframework.jms.remoting.JmsInvokerProxyFactoryBean spring在实现RPC的几种方式上都提供了风格一致的支持. 在这里我打算把几种RPC模型记录下来并作比较. RMI Hessian/Burlap HTTP Invoker JAX-WS RMI 先从最基本的RMI开始

【Spring】几种RPC模型的使用与比较——Hessian/Burlap

Hessian和Burlap,现在进Caucho的网站都几乎见不到这方面的内容了.我也不知道有没有人还会用这两个东东,虽然去年出了一个版本,但上一个版本是在2010年.刚才在群里问了一下有没有人用,结果还真有人用Hessian,他们是C#和Java做通信.Burlap性能更令人头疼,不知道还有没有人提及.虽然不知道使用情况如何,但也在这里简单记录一下,拓展一下思维. Hessian和Burlap都是由Caucho提供的,现在进Caucho的官网人家就一个Resin.这两个东西就像同一件事物的两个

【Spring】几种RPC模型的使用与比较——RMI

上回写到<基于JMS的RPC>时使用到了:·org.springframework.jms.remoting.JmsInvokerServiceExporter·org.springframework.jms.remoting.JmsInvokerProxyFactoryBean spring在实现RPC的几种方式上都提供了风格一致的支持.在这里我打算把几种RPC模型记录下来并作比较. ·RMI·Hessian/Burlap·HTTP Invoker·JAX-WS 先从最基本的RMI开始.RM

Spring远程服务(RPC)

Spring支持几种不同的RPC模型,包括远程方法调用(RMI).Caucho的Hessian和Burlap和Spring自带的HTTP invoker.如下: 无论选择哪一种RPC模型,我们都会发现Spring对每一种模型都提供了风格一致的支持.在所有的模型中,服务都作为Spring所管理的Bean配置到我们的应用中.这是采用一个代理工厂Bean实现的,这个Bean能够像本地对象一样将远程服务装配到其他Bean的属性中去.它的工作原理如下:

rabbitmq五种消息模型整理

目录 0. 配置项目 1. 基本消息模型 1.1 生产者发送消息 1.2 消费者获取消息(自动ACK) 1.3 消息确认机制(ACK) 1.4 消费者获取消息(手动ACK) 1.5 自动ACK存在的问题 1.6 演示手动ACK 2. work消息模型 2.1 生产者 2.2 消费者1 2.3 消费者2 2.4 能者多劳 3. 订阅模型分类 4. 订阅模型-Fanout 4.1 生产者 4.2 消费者1 4.3 消费者2 4.4 测试 5. 订阅模型-Direct 5.1 生产者 5.2 消费者1

Spring框架事务支持模型的优势

全局事务 全局事务支持对多个事务性资源的操作,通常是关系型数据库和消息队列.应用服务器通过JTA管理全局性事务,API非常烦琐.UserTransaction通常需要从JNDI获取,意味着需要与JNDI绑定在一起,且JTA一般只在应用服务器可用,降低了应用代码的可重用性. 本地事务 本地事务面向具体的资源,例如与JDBC连接关联的事务.本地事务易于使用,但不能跨多个事务性资源.使用JDBC管理事务的代码不能在全局JTA事务中运行,因此不能确保跨多个资源的正确性.且本地事务侵入了编程模型. Spr

spring mvc(4)处理模型数据

处理模型数据 Spring MVC 提供了以下几种途径输出模型数据: – ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加 模型数据 – Map 及 Model: 入参为org.springframework.ui.Model.org.springframework.ui. ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中. – @SessionAttributes: 将模型中的某个属性

关于Spring @RequestBody 自动映射模型原理

关于Spring @RequestBody 自动映射模型 2016年10月18日 22:17:12 稻子丶 阅读数:5049 在很多时候,Spring的注解为我们提供了很多方便,但只知道其用法,不懂其执行原理,有时候出错了,很难快速的定位出错原因,今天我想把自己对于@Requestbody这个注解的一点想法和大家分享下. 首先Spring处理一个请求时,请求的入口就是大家在配置文件中配置的 DispathcherServlet 这分发类,其实这个类能够接受到request的原理就是它实现了Ser

一文让你搞懂Spring的统一事务模型

Spring事务的知识体系 进入主题之前,先来了解一下Spring事务,都有哪些内容: Spring事务包含对分布式事务和单机事务的支持,我们用的比较多的是单机事务,也就是只操作一个数据库的事务. 单机事务,按照用法分,又可以分为编程式事务模型(TransactionTemplate)和声明式事务模型(@Transactional注解),后者可以理解为 aop + 编程式事务模型. 编程式事务模型里面涉及到很多知识点,比如统一事务模型.事务传播级别.事务隔离级别等. 我们今天要讲的是其中一点,统