Java 如何使嵌入式Jetty使用AppContext it';在中定义为servlet的父上下文
我有一个独立的java应用程序,它现在运行一个嵌入式Jetty服务器来公开HTTP的RESTful API。从Hibernate到Jetty,它确实大量使用了SpringBean。我已经为Jetty配置了DispatcherServlet(其思想是将来添加非REST API将非常简单,只需制作新的控制器并为dispatcher正确映射即可) 我的应用程序有一个带有main方法的类,该类从我的appContext.xml创建ClassPathXmlApplicationContext来启动一切Java 如何使嵌入式Jetty使用AppContext it';在中定义为servlet的父上下文,java,rest,spring-mvc,spring-3,Java,Rest,Spring Mvc,Spring 3,我有一个独立的java应用程序,它现在运行一个嵌入式Jetty服务器来公开HTTP的RESTful API。从Hibernate到Jetty,它确实大量使用了SpringBean。我已经为Jetty配置了DispatcherServlet(其思想是将来添加非REST API将非常简单,只需制作新的控制器并为dispatcher正确映射即可) 我的应用程序有一个带有main方法的类,该类从我的appContext.xml创建ClassPathXmlApplicationContext来启动一切 A
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>
您正在用
applicationContext.xml
引导Jetty,这反过来又用servlet配置设置Jetty。在其中,您使用指向servlet应用程序上下文的contextConfigLocation
参数配置servlet。即使您嵌入了它,它仍将作为Web应用程序运行。因此,您还需要为servlet提供其他bean的配置。我建议您将jetty设置提取到它自己的文件中,然后将其余bean提取到另一个文件中。然后在contextConfigLocation
中提供另一个上下文文件
编辑
如果您真的需要在jetty和servlet之间共享应用程序上下文,也许您可以使用中的一些信息。这似乎是可能的,但看起来您必须手动连接上下文之间的父/子关系。对我来说,有效的方法是设置ResourceConfig。使用DispatcherServlet,服务器甚至无法为Rest调用提供服务。所以我用了ServletContainer。现在Rest调用工作了,但无法访问ApplicationContext中加载的bean。有资源配置帮助。下面是我在长期研发后提出的配置。我有Jetty版本9.2.11.v20150529和Spring版本4.1.2.2
<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" />
这里的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="/" />
您为什么需要它?我真的看不出有什么好的理由这么做。把你的WebAPP和JETTY视为两个单独的问题。在webapp中定义您需要的bean,并独立于我们的webapp配置jetty。它不是webapp。它没有部署在Tomcat或类似的东西中。它最终是通过“java$CLASSPATH com.mycompany.myapp.Launcher”启动的。Jetty servlet需要访问为应用程序其余部分定义的bean,因为它是一个API。控制器需要能够触摸系统的其他部分来执行请求的操作。我知道这将如何工作,但这看起来不是有点奇怪吗?然后直接加载的配置文件是针对Jetty的,然后加载定义应用程序其余部分的配置文件。这对我来说似乎很奇怪。你必须考虑Jetty是一个网络容器,嵌入的或不是。在web容器中,web应用程序彼此独立运行,每个应用程序都有自己的环境。像这样“继承”服务器的环境是不常见的。我只是尝试了一下,Jetty似乎没有初始化指定配置文件中的任何内容,直到有人想要访问该servlet。所以,在API调用之前,我的其他bean都不存在……我猜“启动时加载”默认为false。你知道我如何在嵌入式xml定义中将其设置为true吗?哈,时间。这也是我的想法,我只是不知道如何在bean定义中实现它。正在努力解决这个问题。
<!-- 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="/" />