在嵌入式Jetty中从main方法向Servlet传递对象的方案问询
我之前也踩过嵌入式Jetty类加载器隔离的坑,要把main里的对象传给Servlet确实不能直接用静态变量,给你分享几个亲测有效的解决方案:
方法1:借助ServletContext全局属性传递
这是最常用的方案,ServletContext是Web应用的全局上下文,只要把对象放到这里,Servlet就能随时拿到。
步骤很简单:
- 在main方法里初始化WebAppContext后,直接把对象存入ServletContext:
WebAppContext webAppContext = new WebAppContext(); // 配置webAppContext的路径、资源等... YourSharedObject yourObj = new YourSharedObject(); webAppContext.setAttribute("sharedObjKey", yourObj);
- 在Servlet里获取对象:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { YourSharedObject obj = (YourSharedObject) getServletContext().getAttribute("sharedObjKey"); // 接下来就可以正常使用这个对象了 }
⚠️ 注意:要确保YourSharedObject的类能被WebAppContext的类加载器和main的类加载器同时访问到——要么把这个类放到Jetty的全局类路径(而非WebApp的WEB-INF/lib下),要么给WebAppContext设置setParentLoaderPriority(true),让它优先委托父类加载器(也就是main的类加载器)加载类,不过后者会打破Web应用的类隔离,需要根据业务场景权衡。
方法2:自定义ContextHandler持有对象
如果你的Web应用不需要完整的WebAppContext,或者想更灵活地控制对象传递,可以自定义一个ContextHandler来持有共享对象:
- 自定义ContextHandler:
public class CustomContextHandler extends ContextHandler { private YourSharedObject sharedObj; public CustomContextHandler(YourSharedObject obj) { this.sharedObj = obj; } public YourSharedObject getSharedObj() { return sharedObj; } }
- 在main里初始化并绑定:
YourSharedObject myObj = new YourSharedObject(); CustomContextHandler context = new CustomContextHandler(myObj); context.setContextPath("/"); context.setHandler(new ServletHolder(new YourServlet())); server.setHandler(context);
- 在Servlet里获取:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { CustomContextHandler context = (CustomContextHandler) req.getAttribute(RequestDispatcher.CONTEXT); YourSharedObject obj = context.getSharedObj(); // 使用对象 }
这个方案的优势是不用依赖ServletContext,类隔离的影响更小,只要自定义的ContextHandler和Servlet在同一个类加载器下就行。
方法3:利用Server级别的全局属性
如果需要在多个Web上下文之间共享对象,可以把对象存在Jetty的Server实例里,Servlet通过Request拿到Server后再取出对象:
- main方法里存储对象:
Server server = new Server(); YourSharedObject yourObj = new YourSharedObject(); server.setAttribute("globalSharedObj", yourObj); // 配置连接器、上下文等...
- Servlet里获取:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Server server = (Server) req.getAttribute("org.eclipse.jetty.server.Server"); YourSharedObject obj = (YourSharedObject) server.getAttribute("globalSharedObj"); // 使用对象 }
这个方案适合跨上下文共享的场景,同样要注意类加载器的可见性问题。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

