`
holdbelief
  • 浏览: 706352 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Axis2 Integration With The Spring Framework

阅读更多

This document is a guide on how to use Axis2 with the Spring Framework

Content

  • Introduction
  • Configuring Axis2 to be Spring aware
    • Programming Model
    • Simple Spring config example
    • With a ServletContext
    • Without a ServletContext
    • Putting it all together
    • Spring inside an AAR
      • The Spring inside an AAR layout
      • The Spring inside an AAR init class
      • Known issues running Spring inside the AAR

Introduction

The idea behind Axis2 and Spring integration is that Axis2 simply needs to have Spring supply one of its pre-loaded beans to the Axis2 Message Receiver defined in the AAR services.xml . While Axis2 typically uses reflection to instantiate the ServiceClass defined in the services.xml that the Message Receiver will use, alternatively one can define a ServiceObjectSupplier that will supply the Object.

This guide will show how to use two separate ServiceObjectSupplier classes that are part of the Axis2 standard distribution: One for use with a ServletContext, and one without. Once configured, the web service itself acts like any other Spring wired bean. These Spring beans can be loaded any way desired, as Axis2 has no configuration file dependencies from Spring. Spring versions 1.2.6, 1.2.8 and 2.0 have been tested, but probably any version would work as only core functionality is required.

This guide assumes some basic knowledge of Axis2. See the User's Guide for more information.

Configuring Axis2 to be Spring Aware

Programming Model

From an Axis2 standpoint, two hooks are needed to be placed into the AAR services.xml: The ServiceObjectSupplier that hooks Axis2 and Spring together, and the name of Spring bean that Axis2 will use as the service. All Message Receivers are currently supported, as would be any Message Receiver that extends org.apache.axis2.receivers.AbstractMessageReceiver .

Simple Spring Config Example

For the purpose of this example, and for no other reason besides simplicity, we'll configure Spring via a WAR file's web.xml. Lets add a context-param and a listener:

<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

Next we will show two examples of Spring's /WEB-INF/applicationContext.xml referenced in the web.xml listener - one using a ServletContext, and one without.

With a ServletContext

This 'with a ServletContext' example applicationContext.xml should be familiar to any Spring user:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
  <!-- Axis2 Web Service, but to Spring, its just another bean that has dependencies -->
  <bean id="springAwareService" class="spring.SpringAwareService">
    <property name="myBean" ref="myBean"/>
  </bean>

  <!-- just another bean / interface with a wired implementation, that's injected by Spring
          into the Web Service -->
   <bean id="myBean" class="spring.MyBeanImpl">
     <property name="val" value="Spring, emerge thyself" />
  </bean>
</beans>

If the service is running in a Servlet Container, i.e., Axis2 will be able to get a hold of ServletContext, the services.xml for the example would be using SpringServletContextObjectSupplier such as:

 <service name="SpringAwareService">
    <description>
        simple spring example
    </description>
    <parameter name="ServiceObjectSupplier" locked="false">org.apache.axis2.extensions.spring.receivers.SpringServletContextObjectSupplier</parameter>
    <parameter name="SpringBeanName" locked="false">springAwareService</parameter>
    <operation name="getValue">
        <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
    </operation>
</service> 

While the above example uses RawXMLINOutMessageReceiver as its messageReceiver class, all Message Receivers are currently supported, as would be any Message Receiver that extends org.apache.axis2.receivers.AbstractMessageReceiver .

Without a ServletContext

In the case Axis2 can't get a ServletContext, ie another transport or running inside the AAR etc, you have the option of defining a bean that takes advantage of Spring's internal abilities (ApplicationContextAware interface, specifically) to provide an Application Context to Axis2, with a bean ref 'applicationContext' :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
  <!-- Configure spring to give a hook to axis2 without a ServletContext -->
  <bean id="applicationContext" 
    class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />

  <!-- Axis2 Web Service, but to Spring, its just another bean that has dependencies -->
  <bean id="springAwareService"
        class="spring.SpringAwareService">
    <property name="myBean" ref="myBean" />
  </bean>

  <!-- just another bean with a wired implementation, that's injected by Spring 
          into the Web Service -->
   <bean id="myBean"
        class="spring.MyBeanImpl">
     <property name="val" value="Spring, emerge thyself" />
  </bean>
</beans>

If the service is _NOT_ running in a Servlet Container, i.e., Axis2 will _NOT_ be able to get a hold of ServletContext or you prefer not to, the services.xml for the example would be using SpringAppContextAwareObjectSupplier such as:

 <service name="SpringAwareService">
    <description>
        simple spring example
    </description>
    <parameter name="ServiceObjectSupplier" locked="false">org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
    <parameter name="SpringBeanName" locked="false">springAwareService</parameter>
    <operation name="getValue">
        <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
    </operation>
</service> 

While the above example uses RawXMLINOutMessageReceiver as its messageReceiver class, all Message Receivers are currently supported, as would be any Message Receiver that extends org.apache.axis2.receivers.AbstractMessageReceiver .

In a 'without a ServletContext' environment, one way you could load the applicationContext.xml file is in a place that will be run once, upon start-up, execute:

import org.springframework.context.support.ClassPathXmlApplicationContext;

 public void createSpringAppCtx(ClassLoader cl)
            throws Exception {

    ClassPathXmlApplicationContext ctx = new
      ClassPathXmlApplicationContext(new String[] {Constants.MY_PATH +
      "spring/applicationContext.xml"}, false);
           ctx.setClassLoader(cl);
           ctx.refresh();

}

Putting It All Together

From here, its just standard Axis2 coding, only now the service has Spring wiring capabilities. The implementation is the same whether using either SpringServletContextObjectSupplier or SpringAppContextAwareObjectSupplier. The service is below:

package spring;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMText;

public class SpringAwareService {

    private MyBean myBean = null;

    //spring 'injects' this implementation
    public void setMyBean(MyBean myBean) {
            this.myBean = myBean;
    }

    // The web service
    public OMElement getValue(OMElement ignore) {
            OMFactory factory=
                OMAbstractFactory.getOMFactory();
            OMNamespace payloadNs= factory.createOMNamespace(
                "http://springExample.org/example1", "example1");
            OMElement payload =
                factory.createOMElement("string", payloadNs);
            OMText response = factory.createOMText(this.myBean.emerge());
            payload.addChild(response);
            return payload;
    }
} 

For those new to Spring, one of the ideas is that you program to an Interface, and the implementation is pluggable. This idea is referenced in the Spring config file above. Below is the interface:

package spring;

/** Interface for Spring aware Bean */
public interface MyBean {
         String emerge();
}

Here's the implementation:

/** Spring wired implementation */
public class MyBeanImpl implements MyBean {

    String str = null;
    // spring 'injects' this value
    public void setVal(String s) {
        str = s;
    }
    // web service gets this value
    public String emerge() {
        return str;
    }
}

Lastly here's the client - not really necessary for the example, other than for completeness:

package client;

import java.io.StringWriter;

import javax.xml.stream.XMLOutputFactory;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

public class TestClient {
    private static EndpointReference targetEPR =
        new EndpointReference(
               "http://localhost:8080/axis2/services/SpringAwareService");

    /**
     * Simple axis2 client.
     *
     * @param args Main
     */
    public static void main(String[] args) {
        try {
            OMFactory factory = OMAbstractFactory.getOMFactory();
            OMNamespace omNs = factory.createOMNamespace(
                        "http://springExample.org/example1", "example1");

            OMElement method = factory.createOMElement("getValue", omNs);
            OMElement value = factory.createOMElement("Text", omNs);
            value.addChild(factory.createOMText(value, "Some String "));
            method.addChild(value);

            ServiceClient serviceClient = new ServiceClient();

            Options options = new Options();
            serviceClient.setOptions(options);
            options.setTo(targetEPR);

            //Blocking invocation
            OMElement result = serviceClient.sendReceive(method);

            StringWriter writer = new StringWriter();
            result.serialize(XMLOutputFactory.newInstance()
                    .createXMLStreamWriter(writer));
            writer.flush();

            System.out.println("Response: " + writer.toString());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
} 

The examples above assumes that both the spring framework jar and the axis2-spring-*.jar are under WEB-INF/lib. In such a case, the classes shown in this tutorial need to be placed in a JAR under WEB-INF/lib. In this example the JAR layout is:

./mySpring.jar
./META-INF
./META-INF/MANIFEST.MF
./spring
./spring/MyBean.class
./spring/MyBeanImpl.class
./spring/SpringAwareService.class

Since all the user classes are in mySpring.jar in this example, the AAR merely contains the services.xml file:

    
./springExample.aar
./META-INF
./META-INF/MANIFEST.MF
./META-INF/services.xml

To run this example, make sure you have the axis2-spring*.jar that comes from the axis2-std-*-bin distro in the server side WEB-INF/lib, as well as the appropriate Spring jar - most will use the full spring.jar, but the minimum requirements are spring-core, spring-beans, spring-context and spring-web. Running the client, you should see this output:

Response: <example1:string xmlns:example1="http://springExample.org/example1" 
  xmlns:tns="http://ws.apache.org/axis2">Spring, emerge thyself</example1:string>

Spring Inside an AAR

Frequently Axis2 users wish to run Spring inside the AAR. Here we show you how. There are four points to be aware of:

(A) You need to configure Spring to use the Axis2 Service Classloader. See the Known issues running Spring inside the AAR area.

(B) Its up to you to load Spring, though we give an example below.

(C) For reasons such as classloader isolation the SpringAppContextAwareObjectSupplier is the best choice.

(D) The springframework jar and axis2-spring-*.jar will be placed inside the AAR under the lib directory. Please MOVE the axis2-spring-*.jar from WEB-INF/lib to inside the AAR, as shown below - it will NOT work otherwise.

  • The Spring inside an AAR layout
    
./springExample.aar
./META-INF
./META-INF/MANIFEST.MF
./META-INF/services.xml
./applicationContext.xml
./lib
./lib/axis2-spring-SNAPSHOT.jar
./lib/spring.jar
./spring
./spring/MyBean.class
./spring/MyBeanImpl.class
./spring/SpringAwareService.class
./spring/SpringInit.class 

As explained in the Without a ServletContext section, likewise the 'Spring inside an AAR' config needs to hook Axis2 and Spring together via a Spring bean. Place the following in your Spring config file:

  <!-- Configure spring to give a hook to axis2 without a ServletContext -->
  <bean id="applicationContext" 
    class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />

  • The Spring inside an AAR init class

One way to initialize Spring inside the AAR is to use the org.apache.axis2.engine.ServiceLifeCycle interface. Here we give an example:

package spring;

import org.apache.axis2.engine.ServiceLifeCycle;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringInit implements ServiceLifeCycle {
	
    /**
     * This will be called during the deployement time of the service. 
     * irrespective
     * of the service scope this method will be called
     */
    public void startUp(ConfigurationContext ignore, AxisService service) {
 
        try {
            System.out.println("Starting spring init");
            ClassLoader classLoader = service.getClassLoader();
            ClassPathXmlApplicationContext appCtx = new
            ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"}, false);
                appCtx.setClassLoader(classLoader);
                appCtx.refresh();
            System.out.println("spring loaded");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * This will be called during the system shut down time. 
     * irrespective
     * of the service scope this method will be called
     */
    public void shutDown(ConfigurationContext ctxIgnore, AxisService ignore) {
    }
}

Here's the services.xml that now includes SpringInit and the SpringAwareService shown above. There is also the composite parameter which is needed when loading Spring in the AAR - see the Known issues running Spring inside the AAR area.

<serviceGroup>
  <!-- Invoke SpringInit on server startup and shutdown -->
  <service name="SpringAwareService" class="spring.SpringInit">
    <description>
         simple spring example - inside the AAR
    </description>
    <!-- need the TCCL param when using spring inside the AAR -->
    <parameter name="ServiceTCCL" locked="false">composite</parameter>
    <parameter name="ServiceObjectSupplier" locked="false">org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
    <parameter name="SpringBeanName" locked="false">springAwareService</parameter>
    <operation name="getValue">
        <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
    </operation>
  </service>
</serviceGroup>
  • Known issues running Spring inside the AAR

The Axis2 classloader strategy by default does not permit Spring to run inside the AAR. To allow Spring to run inside the AAR, the 'composite' parameter is used in the services.xml as shown in the example above. The behavior of 'composite' was the default in the development cycle in between 1.0 and 1.1, but it resulted in the JIRA issue AXIS2-1214 - essentially problems with getting an initContext.lookup() handle inside the AAR. Spring users typically have little desire to use initContext.lookup() however, as they get their Datasources via org.springframework.jdbc.datasource.DriverManagerDataSource in an xml file or with annotations. For ejb home references and the like, Spring provides JndiObjectFactoryBean. While fully testing JndiObjectFactoryBean with ejb has not been done yet - if you do, please send a message to the axis users list - Datasources via Spring inside the AAR have been tested. Basically it works as typically done with Spring, though if you are passing Hibernate XML files you need to put them in a place where Spring will find them. The most flexible way is as follows, using logging in DEBUG mode to see where Spring will look in your jar / class locations:

    <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
                <property name="mappingLocations">
                   <value>classpath*:**/MyEntity.hbm.xml</value>
                </property>
                ...
    </bean> 
分享到:
评论
2 楼 yuanqixun 2010-03-17  
你试过在aar中增加spring的配置的问题吗?我总说applicationContext.xml找不到,axis2的类加载路径包含了service/目录吗?否则的话,怎么在classpath中找到applicaiton.xml?
1 楼 xinkgf 2010-02-24  
真的太感谢楼主了!解决多日的困扰!

相关推荐

    axis2+spring webservice

    标题中的“axis2+spring webservice”指的是使用Apache Axis2框架与Spring框架集成来开发Web服务。Apache Axis2是Java环境中广泛使用的Web服务引擎,它提供了高性能、灵活且可扩展的架构。Spring框架则是一个全面的...

    spring-axis2-test.rar_Axis2 Spring3_axis2_axis2 spring3_axis2 s

    标题中的“spring-axis2-test.rar_Axis2 Spring3_axis2_axis2 spring3_axis2 s”指的是一个关于Spring和Axis2集成的示例项目,它包含了一组用于演示如何在Spring框架中使用Apache Axis2来开发和部署Web服务的源代码...

    Axis2与Spring整合发布多个WebService

    在IT行业中,开发Web服务是常见的任务,而Axis2和Spring框架的整合为开发者提供了强大的工具来实现这一目标。本文将深入探讨如何利用这两个技术来发布多个WebService,并着重讲解项目管理和整合过程。 首先,让我们...

    Axis2集成Spring.doc

    ### Axis2集成Spring知识点 #### 一、概览 本文档旨在介绍如何将Apache Axis2与Spring框架进行集成,以实现灵活的服务部署和管理。在实际应用中,开发者可能需要利用Spring来管理业务对象(例如POJOs),并希望...

    使用Axis2整合Spring(二)

    在本篇博文中,我们将深入探讨如何在Java Web开发中使用Apache Axis2框架与Spring框架进行集成,以实现服务端的高效管理和灵活控制。Apache Axis2是著名的Web服务引擎,而Spring则是流行的Java企业级应用框架,它们...

    spring axis2整合

    在IT行业中,Spring框架是Java企业级应用开发的首选,而Apache Axis2则是知名的Web服务引擎,用于处理SOAP协议和创建Web服务。本篇将详细探讨如何将Spring 3.2.5版本与Axis2 1.6.2版本进行整合,以便在Spring环境中...

    Axis2WebService与Spring的整合

    &lt;bean id="axis2Repository" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&gt; &lt;property name="staticMethod" value="org.apache.axis2.util.URLClassLoaderRepository....

    Spring集成AXIS2的Web_service配置方法

    Spring 集成 AXIS2 的 Web service 配置方法 Spring 是一个流行的 Java 应用程序框架,它提供了一个灵活的方式来构建企业级应用程序。AXIS2 是一个流行的 Web Service 引擎,它提供了一个强大的方式来构建 Web ...

    springboot集成axis2-1.7.9实例

    在本文中,我们将深入探讨如何将Apache Axis2与Spring Boot集成,以构建一个高效、可扩展的Web服务应用。Apache Axis2是Java平台上的一个Web服务框架,它提供了高性能、灵活的服务开发和部署机制。而Spring Boot是...

    Spring集成axis2实现webservice所用到的包

    当我们需要在Spring项目中提供Web服务时,Axis2是一个常用的工具,它是一个高效的Web服务引擎,支持SOAP 1.1和1.2,以及RESTful服务。本篇文章将详细介绍如何在Spring中集成Axis2来实现Web服务,并且会提及相关的Jar...

    axis2 + spring3.2.0

    标题中的"axis2 + spring3.2.0"指的是在Java Web开发中,将Apache Axis2服务框架与Spring 3.2.0版本的依赖管理相结合的技术应用。Apache Axis2是一个用于构建Web服务和SOA(Service-Oriented Architecture,面向服务...

    axis2+spring整合实例

    标题"axis2+spring整合实例"表明了这个压缩包内容是关于如何将Apache Axis2服务框架与Spring框架进行集成的实践案例。Apache Axis2是用于构建Web服务和SOA(Service-Oriented Architecture)的高性能、灵活的开源...

    Spring整合axis2经典

    Spring整合Axis2经典案例解析 在Java Web服务开发中,Spring框架和Apache Axis2是两个重要的组件。Spring作为一款强大的企业级应用框架,提供了一种模块化、灵活的方式来构建应用程序,而Axis2则是Apache组织提供的...

    axis2-spring-1.5.4.jar

    《 Axis2 与 Spring 整合详解:axis2-spring-1.5.4.jar 入门指南》 在Java Web服务开发领域,Apache Axis2 和 Spring 框架都是不可或缺的重要工具。Apache Axis2 是一个高效且可扩展的Web服务引擎,用于处理SOAP...

    axis2与spring集成

    axis2与spring的集成,在application中配置要发布的Java类,然后配置aar文件,在aar打包文件中的services.xml要嵌入 &lt;parameter name="ServiceObjectSupplier"&gt;org.apache.axis2.extensions.spring.receivers....

    axis2和axis2+spring发布服务指南

    标题中的“axis2和axis2+spring发布服务指南”指的是如何使用Apache Axis2框架结合Spring框架来部署和发布Web服务。Axis2是Apache软件基金会开发的一个用于构建和部署Web服务的开源框架,它基于Java语言并支持SOAP和...

    axis2整合spring

    在IT行业中,Axis2和Spring都是极为重要的框架。Axis2是Apache软件基金会开发的一个Web服务引擎,主要用于构建高效、可扩展的Web服务。而Spring框架则是一个全面的企业级应用开发框架,尤其以其强大的依赖注入(DI)...

    axis2+hibernate+Spring测试案例

    在hibernate spring项目基础上通过aixs2-1.4.1把程序发布成webService,包括aixs2以对象数组和AXIOM方式处理map,list的程序代码;和aixs2-1.4-1的jar包

    axis2+spring2.5整合(webservice)

    当我们谈论“Axis2+Spring2.5整合(Web服务)”时,我们指的是将Apache Axis2和Spring框架结合在一起,以便更高效地开发和管理Web服务。 Apache Axis2是Apache软件基金会开发的一个Web服务引擎,它提供了SOAP消息...

    axis2-idea-plugin-1.7.9.zip_axis2_axis2-idea-plugin_idea导入axis2_

    标题中的"axis2-idea-plugin-1.7.9.zip_axis2_axis2-idea-plugin_idea导入axis2_"提到了几个关键元素,分别是"axis2"、"idea-plugin"和"idea导入axis2",这暗示了这个压缩包是用于在IntelliJ IDEA这款集成开发环境...

Global site tag (gtag.js) - Google Analytics