如何在 Jetty 12 中将业务对象注入无注解服务器端点
2024-03-28 15:39:34
在 Jetty 12 服务器端点中注入业务对象
简介
在使用 Jetty 开发 Websocket 应用程序时,有时我们需要将业务对象注入到服务器端点中,以利用其方法处理收到的消息。然而,Jetty 默认情况下不提供这种注入机制,也没有使用注解的方式来实现。本篇博客文章将介绍如何修改 Jetty 的内部工作原理,以便在创建端点对象时使用自定义构造函数来实现业务对象的注入。
步骤
1. 创建自定义 ServerEndpoint 接口
首先,我们需要创建一个扩展自 Jetty javax.websocket.server.ServerEndpoint
接口的自定义 ServerEndpoint
接口,并在其中定义一个用于注入业务对象的构造函数。
public interface MyServerEndpoint extends javax.websocket.server.ServerEndpoint {
MyServerEndpoint(MyBusinessObject businessObject);
}
2. 创建自定义扩展类
接下来,我们需要创建一个自定义扩展类,扩展自 Jetty 的 ServerEndpointConfigurator
类。这个类将被 Jetty 用来创建 ServerEndpoint
对象。
public class MyServerEndpointConfigurator extends ServerEndpointConfigurator {
private MyBusinessObject businessObject;
public MyServerEndpointConfigurator(MyBusinessObject businessObject) {
this.businessObject = businessObject;
}
@Override
public ServerEndpoint getEndpointInstance(ServerEndpointConfig config) {
return new MyServerEndpoint(businessObject);
}
}
3. 修改 Jetty 创建端点对象的方式
在 Jetty 创建 ServerEndpoint
对象时,我们需要使用我们自定义的扩展类。为此,我们需要修改 JakartaWebSocketServletContainerInitializer
类,该类负责将 Websocket 功能添加到 Servlet 容器中。
public static void configure(ServletContextHandler context, ServerContainerInitializerEndpointRegistration registration) {
registration.addEndpoint(MyServerEndpoint.class, MyServerEndpointConfigurator.class);
}
4. 配置 Jetty 使用自定义扩展类
最后,在初始化 Jetty 服务器时,我们需要配置它使用我们自定义的扩展类。
JakartaWebSocketServletContainerInitializer.configure(servletContextHandler, (context, container) -> {
MyBusinessObject businessObject = new MyBusinessObject();
container.addEndpoint(MyServerEndpoint.class, new MyServerEndpointConfigurator(businessObject));
});
通过这些步骤,我们可以将业务对象注入到没有注解的 Jetty 12 服务器端点中。
示例
以下示例代码演示了如何将 MyBusinessObject
实例注入到 MyServerEndpoint
端点中:
public class JettyServer {
private Server server;
private Application application;
public JettyServer(Application application) {
this.application = application;
this.server = new Server(8080);
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
server.setHandler(servletContextHandler);
// Add jakarta.websocket support
JakartaWebSocketServletContainerInitializer.configure(servletContextHandler, (context, container) -> {
MyBusinessObject businessObject = new MyBusinessObject();
container.addEndpoint(MyServerEndpoint.class, new MyServerEndpointConfigurator(businessObject));
});
// Add default servlet (to serve the html/css/js)
// Figure out where the static files are stored.
URL urlStatics = Thread.currentThread().getContextClassLoader().getResource("index.html");
Objects.requireNonNull(urlStatics, "Unable to find index.html in classpath");
String urlBase = urlStatics.toExternalForm().replaceFirst("/[^/]*public class JettyServer {
private Server server;
private Application application;
public JettyServer(Application application) {
this.application = application;
this.server = new Server(8080);
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
server.setHandler(servletContextHandler);
// Add jakarta.websocket support
JakartaWebSocketServletContainerInitializer.configure(servletContextHandler, (context, container) -> {
MyBusinessObject businessObject = new MyBusinessObject();
container.addEndpoint(MyServerEndpoint.class, new MyServerEndpointConfigurator(businessObject));
});
// Add default servlet (to serve the html/css/js)
// Figure out where the static files are stored.
URL urlStatics = Thread.currentThread().getContextClassLoader().getResource("index.html");
Objects.requireNonNull(urlStatics, "Unable to find index.html in classpath");
String urlBase = urlStatics.toExternalForm().replaceFirst("/[^/]*$", "/");
ServletHolder defHolder = new ServletHolder("default", new DefaultServlet());
defHolder.setInitParameter("resourceBase", urlBase);
defHolder.setInitParameter("dirAllowed", "true");
servletContextHandler.addServlet(defHolder, "/");
}
}
quot;, "/");
ServletHolder defHolder = new ServletHolder("default", new DefaultServlet());
defHolder.setInitParameter("resourceBase", urlBase);
defHolder.setInitParameter("dirAllowed", "true");
servletContextHandler.addServlet(defHolder, "/");
}
}
常见问题解答
-
为什么要注入业务对象?
注入业务对象可以使我们访问和使用业务逻辑来处理收到的 Websocket 消息。 -
除了注入业务对象,Jetty 12 还支持哪些类型的注入?
除了业务对象之外,Jetty 12 还支持注入其他类型的对象,例如服务、资源和配置对象。 -
使用自定义扩展类注入业务对象的优点是什么?
使用自定义扩展类注入业务对象的好处是,它使我们能够灵活地控制端点对象的创建过程。 -
是否可以使用反射来注入业务对象?
虽然可以使用反射来注入业务对象,但这是不推荐的,因为反射的性能很低,并且会使代码更难以维护。 -
有哪些替代方案可以注入业务对象?
除了使用自定义扩展类之外,还有其他替代方案可以注入业务对象,例如使用 AOP 框架或依赖注入框架。