Axis2(aar)+ spring,没有servletContext

st6*_*6mm 5 integration spring axis2 mainframe cics

亲爱的Stackoverflow用户,我最近在使用Spring框架的axis2 Web服务的一个特定问题时遇到了很多痛苦.我已经阅读了很多不同的指南并阅读了不同的论坛,但发现人们有同样的问题,但没有解决方案.基本上最后用双手握住显示器并大喊"你发现了什么是BudapestHacker938?".无论如何,我的axis2 Web服务类需要Spring bean,因此它们在Web服务类中自动装配.在我有servletContext的jetty服务器里,一切都运行良好.只需在web.xml中定义所需的侦听器即可.这样的幸福.但不幸的是,在某些方面所有好事都落到了尽头,对我来说,魔鬼是大型机内部的CICS环境.Jetty/Tomcat中没有servletcontext,幸运的是,它仍然支持axis2.因此,根据不同的用户指南,我决定将我的网络服务存档到.aar并将其添加到services文件夹下.Axis2文件夹结构如下:

  • 资料库/
    • 模块
    • 服务

当我构建这个.aar存档时,我也在生成我自己的wsdl,而不是使用axis2内置的wsdl生成器,根据services.xml生成给定类的服务(当我运行axis2server时,不使用因为doesn'就我所知,我喜欢JAX-WS注释.要初始化Spring框架,我需要编写初始化Spring bean的SpringInit类.不幸的是,由于某种原因它也会根据其注释初始化我的web服务类,然后占用主端口(怀疑SpringInit通过自己的Web服务类初始化,因为它也被定义为Spring bean而SpringInit扩展了Axis2类ServiceLifeCycle)我得到JVM BIND异常,它说明地址已被使用.我希望根据存储在WSDL内部的wsdl构建服务,而不是生成新服务,因为我有各种环境:1)本地机器 - Jetty 2)大型机.无论如何,我深入了解了我的services.xml:

<service name="Absence" class="org.services.SpringInit">
<description>
    random description
</description>
<parameter name="ServiceTCCL">composite</parameter>
<parameter name="useOriginalwsdl" locked="false">true</parameter>
<parameter name="ServiceObjectSupplier">org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
<parameter name="ServiceClass">org.services.Absence</parameter>
<parameter name="SpringBeanName">absence</parameter>
<parameter name="SpringContextLocation">META-INF/applicationContextAar.xml</parameter>
</service>
Run Code Online (Sandbox Code Playgroud)

Spring applicationContextAar.xml,为亲爱的Stack社区进行了一点点重构:

<beans>
<bean id="applicationContext" class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:tcp://localhost/~/devDb" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="absence" class="org.services.Absence"></bean>
<bean id="jtemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="ds"></constructor-arg>
</bean>
<bean id="datasetFactory" class="org.vsam.DataSetFactory"></bean>
<bean id="dataManagerFactory" class="org.datamanager.DataManagerFactory"></bean>
<bean id="absenceFactory" class="org.services.AbsenceFactory"></bean>
<bean id="h2Database" class="org.dataset.H2Database"><constructor-arg ref="jtemplate"></constructor-arg>
</bean>
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"></bean>
</beans>
Run Code Online (Sandbox Code Playgroud)

我的SpringInit类看起来像这样:

public class SpringInit implements ServiceLifeCycle {

public void startUp(ConfigurationContext ignore, AxisService service) {

    try {
        ClassLoader classLoader = service.getClassLoader();
        ClassPathXmlApplicationContext appCtx = new
        ClassPathXmlApplicationContext(new String[] {"applicationContextAar.xml"}, false);
            appCtx.setClassLoader(classLoader);
            appCtx.refresh();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public void shutDown(ConfigurationContext ctxIgnore, AxisService ignore) {}
}
Run Code Online (Sandbox Code Playgroud)

现在我们转到org.services.Absence.class,它是一个普通的JAX-WS Web服务类,带有以下头文件(包含JAX-WS注释):

@WebService(name = "AbsenceService", serviceName = "Absence", portName = "Absence",
targetNamespace = "http://www.something.org/Absence")
public class Absence extends ServiceHandlerBase { 

    @Autowired
private AbsenceFactory absenceFactory;

@Autowired
private DataManagerFactory dataManagerFactory;

@Autowired
private DataSetFactory dataSetFactory;


... 

}
Run Code Online (Sandbox Code Playgroud)

包含这样的方法:

@WebMethod
@WebResult(name = "AbsenceResponse")
public SearchAbsenceRecordsResponse invokeSearchAbsenceRecords(
        @WebParam ServiceRequest request,
        @WebParam SearchAbsenceRecordsRequest absenceRequest) {...}
Run Code Online (Sandbox Code Playgroud)

一种替代方法是将"servicejars"文件夹添加到"repository"文件夹中,并使用missing.jar填充它,其中所有依赖项都位于子文件夹"lib"中.然后Axis2会自动运行absense.jar,因为它具有JAX-WS注释.但是当我用SOAP-UI调用Web服务时,它没有初始化Spring,因为我不知道如何在该解决方案中初始化Spring.也许有人对此有任何专业知识.

TL; DR

如何根据注释不能以不启动Web服务类中的服务的方式初始化我的Spring bean,而是根据wsdl构建服务?

欢迎您提出问题.

st6*_*6mm 2

如何在没有 servletcontext 的情况下在 CICS 中初始化 Spring?

基本上直到今天,SOAP Web 服务都是通过 servicejars 发布的,这意味着在存储库文件夹中已经创建了“servicejars”文件夹,其中包含从 Web 服务类构建的 jar。“servicejars”子文件夹“lib”包含 Web 服务 jar 所需的所有依赖项。

首先我从网络上了解到(Axis2主页,有关于axis2和spring集成的说明)在Axis2 Web服务中初始化Spring我需要.aar存档和services.xml中定义的SpringInit服务。但这带来了很多问题,因为旧的架构构建在 jaxws 和 jaxb 上,因此非常需要重构 Web 服务层。Axis2 仅通过“servicejars”解决方案容忍 jaxws 注释。使用 SpringInit 类初始化 Spring 意味着它根据应用程序上下文初始化 Spring bean。现在,它作为单独的 Web 服务运行 Web 服务 bean(上一篇文章中的缺席 bean)并占用 8080 端口,当根据 WSDL 创建 Web 服务时,我收到错误“JVM 绑定地址已在使用中”。所以之后我想我应该根据缺少 Spring bean 创建服务并让 axis2server 生成 WSDL,但 axis2server 不喜欢 jaxws 注释,即使没有它们它也不喜欢我的 jaxb DTO。

因此,我决定放弃.aar架构并回到“servicejars”架构。不幸的是,我没有 services.xml 支持来定义潜在的 SpringInit 服务。

由于 jaxws Web 服务是唯一的入口点,因此我决定执行以下操作(在 Web 服务层中初始化 Spring beans):

@WebService(name = "AbsenceService", serviceName = "Absence", portName = "Absence",
targetNamespace = "http://www.something.org/Absence")
public class Absence extends ServiceHandlerBase { 

private static AbsenceFactory absenceFactory;

private static DataManagerFactory dataManagerFactory;

private static DataSetFactory dataSetFactory;

static {
    try {
        ClassPathXmlApplicationContext appCtx = new
        ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"}, false);
        appCtx.refresh();

        absenceFactory = (AbsenceFactory) appCtx.getBean("absenceFactory", AbsenceFactory.class);
        dataManagerFactory = (DataManagerFactory) appCtx.getBean("dataManagerFactory", DataManagerFactory.class);
        dataSetFactory = (DataSetFactory) appCtx.getBean("datasetFactory", DataSetFactory.class);

    } catch (Exception ex) {
        ex.printStackTrace();
    }

}


... 

}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,当这个类被调用时,它将初始化applicationcontext,并且由于它是静态的,所以所有的spring bean将保留在内存中直到结束(当服务关闭时)。在其他类中,自动装配工作得很好,无需手动连接这些 bean。

最后,我没有找到像我希望的那样通过.aar架构来初始化Spring的可能性,但我在一位高级程序员的指导下找到了解决办法。非常感谢他!现在,所有 StackOverFlow 用户都可以看到可能的解决方案。

编辑:

在 applicationContext.xml 我有:

<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"/>
Run Code Online (Sandbox Code Playgroud)

尝试使用 Absence.class(absence bean) 创建 Web 服务。删除了它,因为我可以在本地计算机上使用 Jetty 预先生成的 WSDL(最初用于在本地计算机中创建 Web 服务,就像我之前说过的,我有本地开发环境,它也应该与 CICS 兼容,现在已解决)。