Spring Boot实现STOMP协议的WebSocket的方法步骤

1.概述

我们之前讨论过Java Generics的基础知识。在本文中,我们将了解Java中的通用构造函数。 泛型构造函数是至少需要有一个泛型类型参数的构造函数。我们将看到泛型构造函数并不都是在泛型类中出现的,而且并非所有泛型类中的构造函数都必须是泛型。

2.非泛型类

首先,先写一个简单的类:Entry,它不是泛型类:

public class Entry {
  private String data;
  private int rank;
}

在这个类中,我们将添加两个构造函数:一个带有两个参数的基本构造函数和一个通用构造函数。

2.1 基本构造器

Entry第一个构造函数:带有两个参数的简单构造函数:

public Entry(String data, int rank) {
  this.data = data;
  this.rank = rank;
}

现在,让我们使用这个基本构造函数来创建一个Entry对象

@Test
public void givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK() {
  Entry entry = new Entry("sample", 1);

  assertEquals("sample", entry.getData());
  assertEquals(1, entry.getRank());
}

2.2 泛型构造器

接下来,第二个构造器是泛型构造器:

public <E extends Rankable & Serializable> Entry(E element) {
  this.data = element.toString();
  this.rank = element.getRank();
}

虽然Entry类不是通用的,但它有一个参数为E的泛型构造函数。

泛型类型E是受限制的,应该实现Rankable和Serializable接口。

现在,让我们看看Rankable接口,下面是其中一个方法:

public interface Rankable {
  public int getRank();
}

假设我们有一个实现Rankable接口的类——Product

public class Product implements Rankable, Serializable {
  private String name;
  private double price;
  private int sales;

  public Product(String name, double price) {
    this.name = name;
    this.price = price;
  }

  @Override
  public int getRank() {
    return sales;
  }
}

然后我们可以使用泛型构造函数和Product创建Entry对象:

@Test
public void givenGenericConstructor_whenCreateNonGenericEntry_thenOK() {
  Product product = new Product("milk", 2.5);
  product.setSales(30);

  Entry entry = new Entry(product);

  assertEquals(product.toString(), entry.getData());
  assertEquals(30, entry.getRank());
}

3.泛型类

接下来,我们看一下泛型类:GenericEntry

public class GenericEntry<T> {
  private T data;
  private int rank;
}

我们将在此类中添加与上一节相同的两种类型的构造函数。

3.1 基础构造器

首先,让我们为GenericEntry类编写一个简单的非泛型构造函数:

public GenericEntry(int rank) {
  this.rank = rank;
}

尽管GenericEntry是泛型类,但这是一个简单的,没有任何参数的构造函数。

现在,我们可以使用此构造函数来创建GenericEntry:

@Test
public void givenNonGenericConstructor_whenCreateGenericEntry_thenOK() {
  GenericEntry<String> entry = new GenericEntry<String>(1);

  assertNull(entry.getData());
  assertEquals(1, entry.getRank());
}

3.2 泛型构造器

接下来,在类中添加第二个构造函数:

public GenericEntry(T data, int rank) {
  this.data = data;
  this.rank = rank;
}

这是一个泛型构造函数,它有一个泛型类型T的数据参数。注意,我们不需要在构造函数声明中添加,因为它是隐含的。

现在,让我们测试一下通用构造函数:

@Test
public void givenGenericConstructor_whenCreateGenericEntry_thenOK() {
  GenericEntry<String> entry = new GenericEntry<String>("sample", 1);

  assertEquals("sample", entry.getData());
  assertEquals(1, entry.getRank());
}

4.不同类型的泛型构造函数

在泛型类中,还有一个构造函数,其泛型类型与类的泛型类型不同:

public <E extends Rankable & Serializable> GenericEntry(E element) {
  this.data = (T) element;
  this.rank = element.getRank();
}

GenericEntry构造函数有类型为E的参数,该参数与T类型不同。让我们看看它的实际效果:

@Test
public void givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK() {
  Product product = new Product("milk", 2.5);
  product.setSales(30);

  GenericEntry<Serializable> entry = new GenericEntry<Serializable>(product);

  assertEquals(product, entry.getData());
  assertEquals(30, entry.getRank());
}

注意:在示例中,我们使用Product(E)创建Serializable(T)类型的GenericEntry,只有当类型E的参数可以转换为T时,我们才能使用此构造函数。

5.多种泛类型

接下来,我们有两个泛型类型参数的泛型类MapEntry:

public class MapEntry<K, V> {
  private K key;
  private V value;

  public MapEntry(K key, V value) {
    this.key = key;
    this.value = value;
  }
}

MapEntry有一个两个参数的泛型构造函数,每个参数都是不同的类型。让我们用一个简单的单元测试测试一下:

@Test
public void givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK() {
  MapEntry<String,Integer> entry = new MapEntry<String,Integer>("sample", 1);

  assertEquals("sample", entry.getKey());
  assertEquals(1, entry.getValue().intValue());
}

6.通配符

最后,我们可以在泛型构造函数中使用通配符:

public GenericEntry(Optional<? extends Rankable> optional) {
  if (optional.isPresent()) {
    this.data = (T) optional.get();
    this.rank = optional.get().getRank();
  }
}

在这儿,我们在GenericEntry构造函数中使用通配符来绑定Optional类型:

@Test
public void givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK() {
  Product product = new Product("milk", 2.5);
  product.setSales(30);
  Optional<Product> optional = Optional.of(product);

  GenericEntry<Serializable> entry = new GenericEntry<Serializable>(optional);

  assertEquals(product, entry.getData());
  assertEquals(30, entry.getRank());
}

请注意,我们应该能够将可选参数类型(Product示例)转换为GenericEntry类型(Serializable示例)。

7.结束语

在本文中,我们学习了如何在泛型和非泛型类中定义和使用泛型构造函数。

原文链接:https://www.baeldung.com/java-generic-constructors

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • springboot websocket简单入门示例

    之前做的需求都是客户端请求服务器响应,新需求是服务器主动推送信息到客户端.百度之后有流.长轮询.websoket等方式进行.但是目前更加推崇且合理的显然是websocket. 从springboot官网翻译了一些资料,再加上百度简单实现了springboot使用websocekt与客户端的双工通信. 1.首先搭建一个简单的springboot环境 <!-- Inherit defaults from Spring Boot --> <parent> <groupId>o

  • 详解spring boot实现websocket

    前言 QQ这类即时通讯工具多数是以桌面应用的方式存在.在没有websocket出现之前,如果开发一个网页版的即时通讯应用,则需要定时刷新页面或定时调用ajax请求,这无疑会加大服务器的负载和增加了客户端的流量.而websocket的出现,则完美的解决了这些问题. spring boot对websocket进行了封装,这对实现一个websocket网页即时通讯应用来说,变得非常简单.  一.准备工作 pom.xml引入 <dependency> <groupId>org.spring

  • SpringBoot webSocket实现发送广播、点对点消息和Android接收

    1.SpringBoot webSocket SpringBoot 使用的websocket 协议,不是标准的websocket协议,使用的是名称叫做STOMP的协议. 1.1 STOMP协议说明 STOMP,Streaming Text Orientated Message Protocol,是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议. 它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消

  • 详解在Spring Boot框架下使用WebSocket实现消息推送

    spring Boot的学习持续进行中.前面两篇博客我们介绍了如何使用Spring Boot容器搭建Web项目以及怎样为我们的Project添加HTTPS的支持,在这两篇文章的基础上,我们今天来看看如何在Spring Boot中使用WebSocket. 什么是WebSocket WebSocket为浏览器和服务器之间提供了双工异步通信功能,也就是说我们可以利用浏览器给服务器发送消息,服务器也可以给浏览器发送消息,目前主流浏览器的主流版本对WebSocket的支持都算是比较好的,但是在实际开发中使

  • 使用 Spring Boot 实现 WebSocket实时通信

    在开发 Web 应用程序时,我们有时需要将服务端事件推送到连接的客户端.但 HTTP 并不能做到.客户端打开与服务端的连接并请求数据,但服务端不能打开与客户端的连接并推送数据. 为了解决这个限制,我们可以建立了一个轮询模式,网页会间隔地轮询服务器以获取新事件.但这种模式不太理想,因为它增加了 HTTP 开销,速度也只能达到与轮询的速率一样快,并且给服务器增加了不必要的负载. 幸运的是,HTML5 WebSocket 出现了.WebSocket 协议允许浏览器与 Web 服务器之间进行低开销的交互

  • 关于Spring Boot WebSocket整合以及nginx配置详解

    前言 本文主要给大家介绍了关于Spring Boot WebSocket整合及nginx配置的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一:Spring Boot WebSocket整合 创建一个maven项目,加入如下依赖 <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId>

  • 详解spring boot Websocket使用笔记

    本文只作为个人笔记,大部分代码是引用其他人的文章的. 在springboot项目中使用websocket做推送,虽然挺简单的,但初学也踩过几个坑,特此记录. 使用websocket有两种方式:1是使用sockjs,2是使用h5的标准.使用Html5标准自然更方便简单,所以记录的是配合h5的使用方法. 1.pom 核心是@ServerEndpoint这个注解.这个注解是Javaee标准里的注解,tomcat7以上已经对其进行了实现,如果是用传统方法使用tomcat发布项目,只要在pom文件中引入j

  • Spring Boot 开发私有即时通信系统(WebSocket)

    1/ 概述 利用Spring Boot作为基础框架,Spring Security作为安全框架,WebSocket作为通信框架,实现点对点聊天和群聊天. 2/ 所需依赖 Spring Boot 版本 1.5.3,使用MongoDB存储数据(非必须),Maven依赖如下: <properties> <java.version>1.8</java.version> <thymeleaf.version>3.0.0.RELEASE</thymeleaf.ve

  • SpringBoot+Websocket实现一个简单的网页聊天功能代码

    最近做了一个SpringBoot的项目,被SpringBoot那简介的配置所迷住.刚好项目中,用到了websocket.于是,我就想着,做一个SpringBoot+websocket简单的网页聊天Demo. 效果展示: 当然,项目很简单,没什么代码,一眼就能明白 导入websocket的包. 通过使用SpringBoot导入包的时候,我们可以发现,很多包都是以 spring-boot-starter 开头的,对于我这种强迫症 ,简直是福音 <dependency> <groupId>

  • Spring Boot实现STOMP协议的WebSocket的方法步骤

    1.概述 我们之前讨论过Java Generics的基础知识.在本文中,我们将了解Java中的通用构造函数. 泛型构造函数是至少需要有一个泛型类型参数的构造函数.我们将看到泛型构造函数并不都是在泛型类中出现的,而且并非所有泛型类中的构造函数都必须是泛型. 2.非泛型类 首先,先写一个简单的类:Entry,它不是泛型类: public class Entry { private String data; private int rank; } 在这个类中,我们将添加两个构造函数:一个带有两个参数的

  • Spring Boot Admin 动态修改日志级别的方法步骤

    [前言] 之前关于线上输出日志一直有个困惑:如何可以动态调整的日志级别,来保证系统在正常运行时性能同时又能在出现问题时打印详细的信息来快速定位问题:最近研究一下Spring Boot Admin中动态日志级别调整,并集成项目中,在此与大家共享: [动态修改日志级别]          一.生产环境日志输出的状况 1.生产环境日志输出的困惑 A.设置日志输出级别为info: (1)优点:可以详细的打印日志,有利于排错: (2)缺点:日志消耗系统的性能较大:只能针对整个系统整体设置日志输出较多,定位

  • Spring Boot 项目发布到 Tomcat 服务器的操作步骤

    第 1 步:将这个 Spring Boot 项目的打包方式设置为 war. <packaging>war</packaging> SpringBoot 默认有内嵌的 tomcat 模块,因此,我们要把这一部分排除掉. 即:我们在 spring-boot-starter-web 里面排除了 spring-boot-starter-tomcat ,但是我们为了在本机测试方便,我们还要引入它,所以我们这样写: <dependency> <groupId>org.s

  • Spring Boot 直接用jar运行项目的方法

    概述 在 Spring Boot 开篇-创建和运行 一文中,介绍了如何创建一个Sprint Boot项目并且运行起来.但是运行的方式是在IDEA中直接Run起来的.还有另一中方式可以可以把Spring Boot程序运行起来,就是直接在命令行中执行jar包. 打成jar包 以往的WEB程序需要打成WAR包,部署到Tomcat上,而Spring Boot支持打包成JAR的形式,就算是JAR里面包含图片.页面等,也是支持的.另外使用JAR包的方式也方便部署到Docker上. 要想把Spring Boo

  • Spring Boot使用yml格式进行配置的方法

    1.yml 格式 现在大家发现,在springboot里还是要用到配置文件的. 除了使用.properties外,springboot还支持 yml格式. 个人觉得yml格式的可读性和..properties比起来差不多,有时候还没有不如properties 看起来那么规整. 但是考虑到很多springboot项目会使用yml格式,还是简单讲讲,主要目的还是为了读懂其他人的项目. 2.同样内容,不同写法 如图所示,左边是application.properties的写法,右边是applicati

  • Spring Boot命令行运行器的实现方法

    CommandLineRunner是一个带有run方法的简单spring引导接口.Spring Boot启动后将自动调用实现CommandLineRunner接口的所有bean的run方法. Command Line Runner在加载应用程序上下文之后以及Spring Application run方法完成之前执行,相当于你的应用的初始化过程,一般用来实现一些数据预先加载或预先处理. @SpringBootApplication <b>public</b> <b>cl

  • Spring Boot + Mybatis多数据源和动态数据源配置方法

    网上的文章基本上都是只有多数据源或只有动态数据源,而最近的项目需要同时使用两种方式,记录一下配置方法供大家参考. 应用场景 项目需要同时连接两个不同的数据库A, B,并且它们都为主从架构,一台写库,多台读库. 多数据源 首先要将spring boot自带的DataSourceAutoConfiguration禁掉,因为它会读取application.properties文件的spring.datasource.*属性并自动配置单数据源.在@SpringBootApplication注解中添加ex

  • spring boot mogodb多条件拼接的解决方法

    起因 当前我们使用mongodb进行查询时,有时我们的条件是分块生成的,它可能来自一个列表里,我们的条件需要根据列表去返回数据,这里有个问题,如果遍历列表,然后每次都去从mongodb里查询数据 ,这种性能显然是不好的,我们需要把条件进行拼接,一次把数据查询出来! 分析 使用Criteria这个对象去构建查询条件,使用orOperator来组合多个Criteria实例,最终将列表里所有条件拼接出来,从返回查询一次即可返回全部数据 . Criteria[] criterias = criteria

  • Spring Boot项目中定制拦截器的方法详解

    这篇文章主要介绍了Spring Boot项目中定制拦截器的方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Servlet 过滤器属于Servlet API,和Spring关系不大.除了使用过滤器包装web请求,Spring MVC还提供HandlerInterceptor(拦截器)工具.根据文档,HandlerInterceptor的功能跟过滤器类似,但拦截器提供更精细的控制能力:在request被响应之前.request被响应之后.视

  • Spring Boot Admin 进行项目监控管理的方法

    一.Spring Boot Admin 的概念 Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序. 应用程序作为Spring Boot Admin Client向为Spring Boot Admin Server注册(通过HTTP)或使用SpringCloud注册中心(例如Eureka,Consul)发现. UI是AngularJs的应用程序,展示Spring Boot Admin Client的Actuator端点上的一些监控.        可

随机推荐