uyfrjk 发表于 2017-2-27 10:58:16

在应用程序中使用Spring启动嵌入式Jetty并让Web程序共享同一个Application Context(二)

  在上一篇《在应用程序中使用Spring启动嵌入式Jetty并让Web程序共享同一个Application Context(一)》 中介绍了其中的一种方法,下面再介绍另一种比较简单的方法。
  这次我们不需要编写自己的 ContextLoader 和 ContextLoaderListener。也不需要在 web.xml 里配置 spring,我们会直接将 application context 传递给 jetty 内部。
  首先要确保 web.xml 里不出现如下的配置代码

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  然后编写一个用于启动 Jetty 的类

package com.test;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
/*
To embed a Jetty server, the following steps are typical:
1. Create the server
2. Add/Configure Connectors
3. Add/Configure Handlers
4. Add/Configure Servlets/Webapps to Handlers
5. start the server
6. wait (join the server to prevent main exiting).
*/
public class JettyDaemon implements ApplicationContextAware{
private Server server;
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void start() throws Exception{
server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(8080);
server.addConnector(connector);
WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/");
webAppContext.setDescriptor("web/WEB-INF/web.xml");
webAppContext.setResourceBase("web");
webAppContext.setConfigurationDiscovered(true);
webAppContext.setParentLoaderPriority(true);
server.setHandler(webAppContext);
// 以下代码是关键
webAppContext.setClassLoader(applicationContext.getClassLoader());
XmlWebApplicationContext xmlWebAppContext = new XmlWebApplicationContext();
xmlWebAppContext.setParent(applicationContext);
xmlWebAppContext.setConfigLocation("");
xmlWebAppContext.setServletContext(webAppContext.getServletContext());
xmlWebAppContext.refresh();
webAppContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
xmlWebAppContext);
server.start();
}
}
  要注意这个类必须实现 ApplicationContextAware 接口,以让 spring 把 application context 设置进来,同时从上面的代码可以看到其实我们自己创建了 XmlWebApplicationContext 并把它传入 webAppContext 的 attribute 集合。
  要主要这个类不要 new 并且执行,而是让 applicationContext 配置它并且执行它。
  applicationContext.xml 的部分配置代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" … … … … … …>
<!-- daemons -->
<bean id="webDaemon" class="com.test.JettyDaemon" init-method="start" />
… … … … … …
  现在应用程序的 main() 方法里面只需加载 Spring context 即可,其他的所有工作就让 Spring 来完成吧。

public static void main(String[] args){   
applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");   
applicationContext.registerShutdownHook();   
}
  注:这里的 Jetty 的版本是 7.0.2
页: [1]
查看完整版本: 在应用程序中使用Spring启动嵌入式Jetty并让Web程序共享同一个Application Context(二)