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



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

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

如果是这样的话,为什么这个实现使用注释这样做呢?在查看此之前,我希望有一个抽象的OnMessage函数需要被覆盖,并为编码器和解码器显式注册函数。为什么websocket不是通过这种"传统"的方式来实现,而是通过注释来实现呢?

谢谢。

Mywhiteboard.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);
    }
}

FigureEncoder.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");
    }
}

FigureDecoder.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与使用(怎么说)使用接口的"传统"API。我就不一一细说了,因为你会发现网上有很多战争。

如果使用得当,注释可以更好地说明类/方法的职责是什么。许多人更喜欢注释,因此它们已经成为一种趋势,并且无处不在。

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

为什么这个实现使用注释这样做?在看这个之前,我希望有一个抽象的OnMessage函数需要被覆盖,并为编码器和解码器显式注册函数。为什么websocket不是通过这种"传统"的方式来实现,而是通过注释来实现呢?

事实上他们没有。注释只是使用API的一种提供方式。如果你不喜欢,你可以按老方法做。以下是来自JSR-356规范:

创建端点有两种主要方法。第一种手段是实现一定的来自Java WebSocket API的API类,具有处理端点生命周期所需的行为;使用和发送消息、发布自身或连接到对等体。通常,此规范将引用此作为一个程序化的终点。第二种方法是修饰一个普通的旧Java对象(POJO)带有来自Java WebSocket API的某些注释。然后实现获取这些并在运行时创建适当的对象,以将POJO部署为websocket端点。通常,该规范将这种端点称为带注释的端点。

再说一遍,人们更喜欢使用注释,这也是你会发现大多数教程使用的,但如果你非常想要它,你可以不使用它们。

相关内容

  • 没有找到相关文章

最新更新