Jpos Q2 服务器 Spring boot 2.3

Jpos Q2 Server with Spring boot 2.3

我们有一个带有 Q2 服务器和 Spring MVC 的现有系统,配置如下。 Q2 服务器是在启动 Httpservlet 时创建的,它运行良好,spring bean 可以自动连接到 ISORequestlistner。现在正在转换为 Spring boot 2.3。一旦我在 Spring 引导中使用 ServletRegistrationBean 启动了相同的 Httpservlet,Q2 服务器启动并可以向它发送请求。但是自动接线不起作用。一旦我检查。一旦他的请求在 ISORequest 监听器中处理,Spring 上下文不可见,因为 Q2 服务器使用不同的 class 加载器。

<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 请求时它变为空。

第二次尝试 我尝试了几种解决方案,例如 github repo。但是我没有工作。 https://github.com/vmantek/chimera

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

这几天一直在找,试了好几种方法。 问题是 Spring 在特定的 class 加载程序中启动。但是当你启动 Q2 Server as

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

Q2 服务器在不同的 classloader 中启动。因此 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 class.

中实现 self-autowiring
 @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