1

我有一个独立的 Java 应用程序,它现在运行一个嵌入式 Jetty 服务器来为 HTTP 公开一个 RESTful API。从 Hibernate 到 Jetty,它确实大量使用了 Spring bean。我为 Jetty 配置了 DispatcherServlet(想法是将来添加非 REST API 就像制作新的控制器并为调度程序正确映射它一样简单)。

我的应用程序有一个带有 main 方法的类,它从我的 appContext.xml 创建一个 ClassPathXmlApplicationContext 来启动一切。

ApplicationContext ac= new ClassPathXmlApplicationContext(new String[] { "appContext.xml" });

我不知道如何使在 DispatcherServlet 的上下文配置文件中定义的 bean 可以访问在定义 jetty 的 appContext.xml 中定义的 bean。我的 Jetty 定义如下所示:

<bean id="JettyServer" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">

    <constructor-arg>
            <bean id="threadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
                <property name="minThreads" value="2"/>
                <property name="maxThreads" value="10"/>
            </bean>
    </constructor-arg>

    <property name="connectors">
        <list>
            <bean id="Connector" class="org.eclipse.jetty.server.ServerConnector">
                <constructor-arg ref="JettyServer"/>
                <property name="port" value="8090"/>
            </bean>
        </list>
    </property>

    <property name="handler">
        <bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
            <property name="handlers">
                <list>
                    <bean class="org.eclipse.jetty.servlet.ServletContextHandler">
                        <property name="contextPath" value="/"/>
                        <property name="servletHandler">
                            <bean class="org.eclipse.jetty.servlet.ServletHandler">
                                <property name="servlets">
                                    <list>
                                        <bean class="org.eclipse.jetty.servlet.ServletHolder">
                                            <property name="name" value="DefaultServlet"/>
                                            <property name="servlet">
                                                <bean class="org.springframework.web.servlet.DispatcherServlet"/>
                                            </property>
                                            <property name="initParameters">
                                                <map>
                                                    <entry key="contextConfigLocation" value="classpath:./DefaultServlet.xml" />
                                                </map>
                                            </property>
                                        </bean>
                                    </list>
                                </property>
                                <property name="servletMappings">
                                    <list>
                                        <bean class="org.eclipse.jetty.servlet.ServletMapping">
                                            <property name="pathSpecs">
                                                <list><value>/</value></list>
                                            </property>
                                            <property name="servletName" value="DefaultServlet"/>
                                        </bean>
                                    </list>
                                </property>
                            </bean>
                        </property>
                    </bean>
                    <bean class="org.eclipse.jetty.server.handler.RequestLogHandler">
                        <property name="requestLog">
                            <bean class="org.eclipse.jetty.server.NCSARequestLog">
                                <constructor-arg value="/opt/impulse/logs/jetty-yyyy_mm_dd.log"/>
                                <property name="extended" value="false" />
                            </bean>
                        </property>
                    </bean>
                </list>
            </property>
        </bean>
    </property>

  </bean>

然后在 DefaultServlet.xml 中,我尝试定义一个带有属性的 bean,它引用了 appContext.xml 中定义的一个 bean,这就是中断。

<bean id="restApiController" class="com.mycompany.myapp.api.controllers.RESTfulController">
    <property name="someBean" ref="someBean"/>
</bean>
4

2 回答 2

2

您正在使用 引导 Jetty applicationContext.xml,而后者又使用您的 servlet 配置设置了 Jetty。contextConfigLocation在其中,您正在使用指向 servlet 应用程序上下文的参数配置您的 servlet 。即使您嵌入它,它仍将作为 web 应用程序运行。因此,您还需要为您的 servlet 提供其他 bean 的配置。我建议您将码头设置提取到它自己的文件中,然后将其余的 bean 提取到不同的文件中。然后,您在contextConfigLocation.

编辑

如果你真的需要在 jetty 和你的 servlet 之间共享应用程序上下文,也许你可以使用这个博客中的一些信息。这似乎是可能的,但看起来您必须手动连接上下文之间的父/子关系。

于 2013-04-17T21:14:26.680 回答
0

对我来说,有效的是 ResourceConfig 的设置。使用 DispatcherServlet 服务器甚至无法提供 Rest 调用。所以我使用了 ServletContainer。现在 Rest 调用工作但无法访问 ApplicationContext 中加载的 bean。有 ResourceConfig 注册帮助。下面是我经过长时间研发后得出的配置。我有 Jetty 版本 9.2.11.v20150529 和 Spring 4.1.2.RELEASE

<bean class="org.eclipse.jetty.servlet.ServletHolder">
    <property name="name" value="DefaultServlet"/>
       <property name="servlet">              
             <bean id="servletContainer" class="org.glassfish.jersey.servlet.ServletContainer">
                <constructor-arg>
                    <ref bean="config" />
                </constructor-arg>
            </bean>                                            
         </property>
      </bean>
<bean id="config" class="org.glassfish.jersey.server.ResourceConfig" />

基本上我在 ServletContainer 下设置了 ResourceConfig。然后在应用程序中,我获取了在我的 applicationContext 中加载的所有 bean 并使用此资源配置注册,如下所示

ResourceConfig restConfig = (ResourceConfig)webContext.getBean("config");

String[] beans = context.getBeanDefinitionNames();

for(String bean : beans)
  restConfig.registerInstances(context.getBean(bean));

好吧,这里的 webContext 是需要的 WebAppContext 而不是 ServletContaxtHandler。因此,而不是问题中提到的以下行

 <bean class="org.eclipse.jetty.servlet.ServletContextHandler">
 <property name="contextPath" value="/"/>

我有

    <!-- To work with Spring , we need WebAppContext instead of ServletContext -->
    <!-- <bean id="servletContextHandler" class="org.eclipse.jetty.servlet.ServletContextHandler"> -->
    <constructor-arg name="webApp" value="./target/classes/" />
    <constructor-arg name="contextPath" value="/" />
于 2017-08-03T12:41:29.143 回答