装有Spring Boot 2.3的Jpos Q2 Server

问题描述

我们有一个带有Q2 Server和Spring MVC且具有以下配置的现有系统。 Q2服务器是在启动HttpServlet时创建的,并且运行良好,可以使用ISORequestlistner自动连接spring bean。现在将其转换为Spring boot 2.3。一旦在Spring Boot中使用ServletRegistrationBean启动了同一个HttpServlet,Q2服务器就会启动并可以向其发送请求。但是自动接线无效。一旦我检查。一旦他的请求在ISORequest列表器中进行处理,由于Q2服务器正在使用其他类加载器,因此Spring上下文不可见。

<server class="org.jpos.q2.iso.QServer" logger="Q2" name="DownloadServer-A">
<attr name="port" type="java.lang.Integer">6400</attr>
<attr name="minSessions" type="java.lang.Integer">10</attr>
<attr name="maxSessions" type="java.lang.Integer">1100</attr>
<channel name="DownloadServer-A-Channel" class="org.jpos.iso.channel.NACChannel" logger="Q2"
packager="org.jpos.iso.packager.GenericPackager" header="6000010000">
<property name="packager-config" value="/app/repository/q2serverconfig/resources/Download_generic.xml" />
</channel>
<request-listener class="DownloadServerAListener" logger="Q2">
<property name="space" value="transient:default" />
<property name="queue" value="TransactionQueue" />
<property name="timeout" value="35000" />
</request-listener>
</server>
第一次尝试 尝试使用ApplicationContextAware创建静态ApplicationContext并在ISORequestListner中进行了尝试。但是,当向Q2服务器接收TCP请求时,它变为null。

第二次尝试 我尝试了以下github repo之类的几种解决方案。但是我没工作。 https://github.com/vmantek/chimera

有没有人试图将Spring Application上下文中的ISO Server作为bean启动?我的意思是使用Q2.start()在@Configuration类中启动ISO Server。 Q2.start将在单独的类加载器中启动。我不希望它发生。

解决方法

这几天我一直在寻找,并且正在尝试几种方法。 问题在于,Spring正在特定类加载器中启动。但是当您启动Q2 Server时

Q2 q2Server = new Q2(<deploydir>);
q2Server.start();

Q2服务器在另一个类加载器中启动。因此,SpringContext无法用于自动接线。 SpringBeanAutowiringSupport依赖于ContextLoader来检索当前应用程序上下文,并始终获取null。

解决方法

您可以注册一个实现org.springframework.boot.context.embedded.ServletContextInitializer的bean,以便在startup()期间检索应用程序上下文。

@Configuration
public class WebApplicationContextLocator implements ServletContextInitializer {
    private static WebApplicationContext webApplicationContext;

    public static WebApplicationContext getCurrentWebApplicationContext() {
        return webApplicationContext;
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
      webApplicationContext = 
            WebApplicationContextUtils.getWebApplicationContext(servletContext);
    }
}

然后,您可以在ISORequestListener类中实现自动装配。

 @Component
 public class ServiceImpl implements ISORequestListener {
    @Autowired
    private BackendService backendService;

    public ServiceImpl() {
           AutowiredAnnotationBeanPostProcessor bpp = new 
                       AutowiredAnnotationBeanPostProcessor();
           WebApplicationContext currentContext = 
                       WebApplicationContextLocator.getCurrentWebApplicationContext();
           bpp.setBeanFactory(currentContext.getAutowireCapableBeanFactory());
           bpp.processInjection(this);
    }

}

然后自动接线工作完美。我受到以下答案的启发。 Spring Boot register JAX-WS webservice as bean