2013-04-17 4 views
1

У меня есть автономное приложение Java, которое теперь запускает встроенный сервер Jetty для предоставления RESTful API для HTTP. Он действительно использует весенние бобы для всего, начиная от Hibernate и Jetty. У меня Jetty настроен с DispatcherServlet (мысль, что добавление API без REST в будущем будет таким же простым, как создание нового контроллера и правильное отображение его для диспетчера).Как сделать встроенный Jetty использовать AppContext, он определен как родительский контекст для сервлетов.

У моего приложения есть класс с основным методом, который создает класс ClassPathXmlApplicationContext из моего appContext.xml, чтобы начать все.

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

Я не знаю, как сделать фасоль, определенной в конфигурационном файле контекста для DispatcherServlet имеет доступ к фасоли, определенной в appContext.xml, где определяются мол. Мое определение 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 Старается определенным боб с ссылками свойства бин определяется в appContext.xml, что и ломается.

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

Зачем вам это? Я не могу по-настоящему понять причину этого. Рассмотрите свой веб-сайт и пристань как две отдельные проблемы. Определите компоненты, которые вам нужны в webapp, и настройте причал независимо от нашего webapp. – NilsH

+0

Это не webapp. Он не используется в Tomcat или что-то в этом роде. В конечном итоге он запускается с помощью «java $ CLASSPATH com.mycompany.myapp.Launcher». Серверу Jetty нужен доступ к компонентам, определенным для остальной части приложения, потому что он должен быть API. Контроллер должен иметь возможность касаться других частей системы для выполнения запрошенных действий. – tdimmig

ответ

1

Вы самонастройки Jetty с applicationContext.xml, который, в свою очередь настраивает причалом с конфигурации сервлета. В нем вы настраиваете свой сервлет с параметром contextConfigLocation, указывающим на контекст приложения сервлета. Он все равно будет работать как webapp, даже если вы его вставляете. Таким образом, вам необходимо предоставить ваш сервлет с конфигурацией другим вашим фасолям. Я предлагаю вам извлечь настройку причала в собственный файл, а затем остальные ваши компоненты в другом файле. Затем вы передаете другой файл контекста в contextConfigLocation.

Редактировать

Если вам действительно нужно разделить контекст приложения между причалом и сервлет, может быть, вы можете использовать некоторые из информации, содержащейся в this blog. Это кажется возможным, но похоже, что вам нужно связать отношения между родителями и дочерними элементами между контекстами вручную.

+0

Я вижу, как это сработает, но разве это не кажется странным? Конфигурационный файл, который я загружаю непосредственно, для Jetty, затем загружает файл конфигурации, который определяет остальную часть моего приложения. Это просто странно обратное мне. – tdimmig

+0

Вы должны учитывать, что Jetty - это веб-контейнер, встроенный или нет. В веб-контейнере веб-приложения работают изолированно друг от друга, каждый из которых имеет свою собственную среду. Нередко «наследовать» такую ​​среду сервера. – NilsH

+0

Я просто попробовал это, похоже, что Jetty не инициализирует ничего в указанном файле конфигурации, пока что-то не захочет получить доступ к этому сервлету. Итак, ни один из моих других beans не существует до тех пор, пока не будет создан вызов API ... – tdimmig

0

Для меня работала настройка ResourceConfig. С сервером DispatcherServlet даже не удалось выполнить вызов Rest. Поэтому я использовал ServletContainer. Теперь вызов Rest работал, но не смог получить доступ к компонентам, загруженным в ApplicationContext. Там была зарегистрирована регистрация ResourceConfig. Ниже моя конфигурация, я пришел после того, как долго R & D. У меня была 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" /> 

В основном я поставил ResourceConfig под ServletContainer. Тогда в приложении, я принес все бобы, загруженные в моем ApplicationContext и регистрации этой конфигурации ресурсов, как показано ниже

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="/" />