0

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

<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 Application 上下文中将 ISO Server 作为 bean 启动?我的意思是使用 Q2.start() 在 @Configuration 类中启动 ISO Server。Q2.start 将在一个单独的类加载器中启动。我不希望它发生。

4

1 回答 1

0

这几天我一直在寻找,我尝试了几种方法。问题是 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 将 JAX-WS webservice 注册为 bean

于 2020-09-16T16:38:44.313 回答