返回

如何在 Jetty 12 中将业务对象注入无注解服务器端点

java

在 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, "/"); } }

常见问题解答

  1. 为什么要注入业务对象?
    注入业务对象可以使我们访问和使用业务逻辑来处理收到的 Websocket 消息。

  2. 除了注入业务对象,Jetty 12 还支持哪些类型的注入?
    除了业务对象之外,Jetty 12 还支持注入其他类型的对象,例如服务、资源和配置对象。

  3. 使用自定义扩展类注入业务对象的优点是什么?
    使用自定义扩展类注入业务对象的好处是,它使我们能够灵活地控制端点对象的创建过程。

  4. 是否可以使用反射来注入业务对象?
    虽然可以使用反射来注入业务对象,但这是不推荐的,因为反射的性能很低,并且会使代码更难以维护。

  5. 有哪些替代方案可以注入业务对象?
    除了使用自定义扩展类之外,还有其他替代方案可以注入业务对象,例如使用 AOP 框架或依赖注入框架。