java 是否可以从Web上下文中定位Spring非Web上下文?

tquggr8v  于 2023-04-19  发布在  Java
关注(0)|答案(2)|浏览(163)

我有一个Spring应用程序,它在Jetty的嵌入式示例中启动REST服务,Jetty本身是从Spring启动的。
初始Spring上下文有一个集成和数据库层,并启动Jetty示例。Jetty然后调用它自己的应用程序上下文文件,该文件公开REST服务。
我想知道是否有某种方法可以将初始Spring上下文暴露给从Jetty内部运行的Web上下文。不幸的是,我无法部署完整的J2EE服务器,并且我不确定是否从Web上下文运行所有内容,依赖Jetty来管理线程等。

p3rjfoxz

p3rjfoxz1#

我假设您在Jetty的web.xml中有一个ContextLoaderListener,这就是Spring Web上下文的创建方式。
1.从jetty的web.xml中删除ContextLoaderListener(但保留context-paramcontextConfigLocation
1.子类ContextLoader,覆盖loadParentContext()以返回初始Spring上下文。
1.在启动Jetty之后创建ContextLoader子类的示例。
1.在此示例上调用initWebApplicationContext(context.getServletContext().getContext()),其中“context”是org.mortbay.jetty.servlet.Context

zc0qhyus

zc0qhyus2#

所以我在上面ericacm的基础上找到了一个更好的答案,唯一的原因是你仍然可以在web.xml文件中使用<load-on-startup>作为servlet。
在嵌入Jetty服务器时,需要创建一个WebAppContext。超类ContextHandler允许您设置一个包含ServletContextListenerEventListener数组。
所以解决方案是扩展ContextLoader并实现Spring的ApplicationContextAwareServletContextListener接口。loader允许您返回contextware接口设置的父上下文,而listener通过contextInitialized()提供ServletContext
然后,您可以在任何Jetty组件之前对其进行初始化,并在Jetty服务器加载时访问完全填充的ServletContext,该服务器在任何Web应用程序本身初始化之前被调用。
监听器实现:

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.ContextLoader;

public final class EmbeddedJettySpringContextLoaderListener 
    extends ContextLoader 
    implements ApplicationContextAware,
               ServletContextListener
{
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * Returns the parent application context as set by the
     * {@link ApplicationContextAware} interface.
     * 
     * @return The initial ApplicationContext that loads the Jetty server.
     */
    @Override
    protected ApplicationContext loadParentContext(ServletContext servletContext) {
        return this.applicationContext;
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        super.initWebApplicationContext(sce.getServletContext());
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //not needed
    }
}

WebAppContext的Jetty配置(最终由服务器引用):

<!-- Loads this application context as the parent of the web application context. -->
<bean id="parentContextLoaderListener" class="com.citi.matrix.server.restapi.EmbeddedJettySpringContextLoaderListener" />

<bean id="restApiWebAppContext" class="org.mortbay.jetty.webapp.WebAppContext">
  <property name="displayName" value="RestApi" />
  <property name="contextPath" value="/" />
  <!-- the value for war, must be a relative path to the root of the application, and does not use the classpath. -->
  <property name="war" value="${WEBAPPS_HOME}/rest-api" />
  <property name="eventListeners">
    <ref  local="parentContextLoaderListener" />
  </property>
  <property name="configurationClasses">
    <list>
      <value>org.mortbay.jetty.webapp.WebInfConfiguration</value>
      <value>org.mortbay.jetty.webapp.WebXmlConfiguration</value>
      <value>org.mortbay.jetty.webapp.JettyWebXmlConfiguration</value>
    </list>
  </property>
  <property name="logUrlOnStart" value="true" />
</bean>

相关问题