Java 注释和 websocket - 为什么使用注释而不是传统方法?

标签 java netbeans websocket annotations

请查看我在下面发布的代码。仅供引用,这是来自 Oracle 网站的 websocket 示例: https://netbeans.org/kb/docs/javaee/maven-websocketapi.html

我的问题是,这是如何运作的?! -- 特别是 MyWhiteboardbroadcastFigure 函数。它不是一个被覆盖的抽象函数,也没有像传统意义上那样“注册”到另一个类。我看到它的唯一方法是当编译器看到 @OnMessage 注释时,它会在收到新消息时插入 broadcastFigure 调用到编译代码中。但在调用此函数之前,它会通过 FigureDecoder 类处理接收到的数据 - 基于在注释 @ServerEndpoint 中指定的解码器。在 broadcastFigure 中,当调用 sendObject 时,编译器会根据注释 @ServerEndpoint< 中指定的内容插入对 FigureEncoder 的引用。这准确吗?

如果是这样,为什么这个实现使用注释以这种方式做事?在看这个之前,我本以为会有一个抽象的 OnMessage 函数需要被覆盖,以及编码器和解码器的显式注册函数。为什么 websocket 实现不是通过这种“传统”方法,而是通过注释来实现?

谢谢。

我的白板.java:

@ServerEndpoint(value = "/whiteboardendpoint", encoders = {FigureEncoder.class}, decoders = {FigureDecoder.class})
public class MyWhiteboard {

    private static Set<Session> peers = Collections.synchronizedSet(new HashSet<Session>());

    @OnMessage
    public void broadcastFigure(Figure figure, Session session) throws IOException, EncodeException {
        System.out.println("broadcastFigure: " + figure);
        for (Session peer : peers) {
            if (!peer.equals(session)) {
                peer.getBasicRemote().sendObject(figure);
            }
        }
    }

    @OnError
    public void onError(Throwable t) {
    }

    @OnClose
    public void onClose(Session peer) {
        peers.remove(peer);
    }

    @OnOpen
    public void onOpen(Session peer) {
        peers.add(peer);
    }

}

图形编码器.java

public class FigureEncoder implements Encoder.Text<Figure> {

    @Override
    public String encode(Figure figure) throws EncodeException {
        return figure.getJson().toString();
    }

    @Override
    public void init(EndpointConfig config) {
        System.out.println("init");
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }

}

图形解码器.java:

public class FigureDecoder implements Decoder.Text<Figure> {

    @Override
    public Figure decode(String string) throws DecodeException {
        JsonObject jsonObject = Json.createReader(new StringReader(string)).readObject();
        return new Figure(jsonObject);
    }

    @Override
    public boolean willDecode(String string) {
        try {
            Json.createReader(new StringReader(string)).readObject();
            return true;
        } catch (JsonException ex) {
            ex.printStackTrace();
            return false;
        }
    }

    @Override
    public void init(EndpointConfig config) {
        System.out.println("init");
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }

}

最佳答案

注解有其优点和缺点,关于选择创建基于注解的 API 与使用接口(interface)的(你怎么说)“传统”API,有很多话要说。我不会深入讨论,因为您会在网上找到很多 war 。

如果使用得当,注解可以提供有关类/方法职责的更好信息。许多人更喜欢注释,因此它们已成为一种趋势,并且无处不在。

说完这些,让我们回到你的问题:

Why did this implementation do things this way using annotations? Before looking at this, I would have expected there to be an abstract OnMessage function which needs to be overridden and explicit registration functions for Encoder and Decoder. Instead of such a "traditional" approach, why does the websocket implementation do it via annotations?

实际上他们没有。注解只是提供的一种使用 API 的方式。如果您不喜欢它,那么您可以按照旧方法进行。这是来自 JSR-356 规范:

There are two main means by which an endpoint can be created. The first means is to implement certain of the API classes from the Java WebSocket API with the required behavior to handle the endpoint lifecycle, consume and send messages, publish itself, or connect to a peer. Often, this specification will refer to this kind of endpoint as a programmatic endpoint. The second means is to decorate a Plain Old Java Object (POJO) with certain of the annotations from the Java WebSocket API. The implementation then takes these annotated classes and creates the appropriate objects at runtime to deploy the POJO as a websocket endpoint. Often, this specification will refer to this kind of endpoint as an annotated endpoint.

同样,人们更喜欢使用注释,这就是您会发现大多数教程都在使用的注释,但如果您非常想要它,您也可以不用它们。

关于Java 注释和 websocket - 为什么使用注释而不是传统方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24931615/

相关文章:

javascript - Websocket 的正确方法

python - Django 的实时选项(Websockets、flash、轮询)?

java - 使用方法在 Java 列表中搜索匹配项

JavaFX 预加载器和 Netbeans

java - 如何只允许在服务器上创建 1 个 Java 信号量?

java - 打开 netbeans 时出现 JVM 创建失败消息

java - 将 Apache Ivy 与 netbeans 结合使用

javascript - JavaScript websocket可以从服务器获取返回值吗?

java - 我一直坚持删除()

java - 每个用户可能有多个 session