解决springboot整合websocket、redis、openfeign,redisTemplate,openfeign的类无法注入的问题

news2024/11/17 21:33:10

在部分业务中,我们需要使用长连接,我们可以使用http长连接或者websocket,在springboot作为后端的框架中, 可以借用的技术是(netty,websocket)

版本如下 

软件版本号
jdk21
springboot

3.1.5

springcloud

2022.0.4

 场景复现

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>testDi</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>testDi</name>
    <description>testDi</description>
    <properties>
        <java.version>21</java.version>
        <spring-cloud.version>2022.0.4</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 配置类

package com.example.testdi.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;

@Configuration
public class WebsocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(8192 * 4);
        container.setMaxBinaryMessageBufferSize(8192 * 4);
        return container;
    }
}

rpc类

package com.example.testdi.rpc;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@FeignClient(value = "http://localhost:9090")
public interface TestRpc {

    @GetMapping("/hello")
    @ResponseBody
    String hello();
}

websocket类

@Slf4j
@Component
@ServerEndpoint(value = "/example")
public class ExampleWebsocket {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private TestRpc testRpc;

    @OnOpen
    public void open(Session session) {
        log.info("===============open=================");
        log.info("redisTemplate: {}", redisTemplate);
        log.info("testRpc: {}", testRpc);
    }
}

启动类

@EnableFeignClients
@SpringBootApplication
public class TestDiApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestDiApplication.class, args);
    }

}

配置文件

spring:
  data:
    redis:
      host: xxx.xxx.xxx.xxx
      database: xx
      port: xxxx
      timeout: xxxx
      password: xxxxxxxxxxxxxxx
server:
  port: 9090

效果

可以看到都是空指针

问题分析

可能是bean没有注入到spring容器吗?

修改启动类

package com.example.testdi;

import jakarta.annotation.Resource;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ApplicationContext;

import java.util.Arrays;
import java.util.List;

@EnableFeignClients
@SpringBootApplication
public class TestDiApplication extends SpringBootServletInitializer implements CommandLineRunner {

    @Resource
    private ApplicationContext appContext;

    public static void main(String[] args) {
        SpringApplication.run(TestDiApplication.class, args);
    }


    @Override
    public void run(String... args) throws Exception
    {
        String[] beans = appContext.getBeanDefinitionNames();
        Arrays.sort(beans);
        List<String> list = Arrays.stream(beans).filter(ele -> ele.contains("TestRpc") || ele.contains("redisTemplate")).toList();
        for (String bean : list)
        {
            System.out.println(bean + " of Type :: " + appContext.getBean(bean).getClass());
        }
    }
}

查看控制台

发现并不是上述情况

没获取到/获取的方式错误

解决方案 

使用辅助类

package com.example.testdi.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationHelper implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationHelper.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }

}

修改websocket代码

package com.example.testdi.websocket;

import com.example.testdi.rpc.TestRpc;
import com.example.testdi.utils.ApplicationHelper;
import jakarta.annotation.Resource;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@ServerEndpoint(value = "/example")
public class ExampleWebsocket {

    private RedisTemplate<String, Object> redisTemplate= (RedisTemplate<String, Object>) ApplicationHelper.getBean("redisTemplate");

    private TestRpc testRpc= (TestRpc) ApplicationHelper.getBean("com.example.testdi.rpc.TestRpc");

    @OnOpen
    public void open(Session session) {
        log.info("===============open=================");
        log.info("redisTemplate: {}", redisTemplate);
        log.info("testRpc: {}", testRpc);
    }
}

效果

一些问题 

怎么测试websocket接口

这里推荐2个,一个是postman,一个是网站

postman 

即可开始测试

网站

这边推荐测试网站测试,支持ws/wss

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1180841.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业微信开启接收消息+验证URL有效性

企业微信开启接收消息验证URL有效性 &#x1f4d4; 千寻简笔记介绍 千寻简笔记已开源&#xff0c;Gitee与GitHub搜索chihiro-notes&#xff0c;包含笔记源文件.md&#xff0c;以及PDF版本方便阅读&#xff0c;且是用了精美主题&#xff0c;阅读体验更佳&#xff0c;如果文章对…

[极客大挑战 2019]Upload 1

题目环境&#xff1a; 根据题目和环境可知此题目是一道文件上传漏洞 编写一句话木马脚本<?php eval($_POST[shell]);?>将脚本文件更改为jpg图片文件我这里是flag.jpg上传文件并burpsuite抓包Repeater重放 报错一句话木马里面有<?字符 换一种一句话木马继续编写木马…

iOS实现代码混淆

​ 目录 前言 ipaguard界面概览 ipaguard启动界面 ipaguard代码混淆界面 资源文件混淆界面 重签名界面 前言 本文章向大家介绍iOS实现代码混淆&#xff0c;主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项&#xff0c;具有一定的参考价值&#xff0c;需…

高德地图设置电子围栏

高德地图设置电子围栏 需求效果图代码实现 需求 给地图上人员锚点设置围栏区域&#xff0c;如果在此区域内则是在线状态&#xff0c;不在此区域内则是离线状态 效果图 双击可编辑或清除当前围栏 代码实现 前端实现区域框选&#xff1a; //引入高德地图sdk"amap/amap…

Python语言高级实战-内置函数super()的使用之类的多继承(附源码和实现效果)

实现功能 super()函数的调用顺序是按照方法解析顺序&#xff08;Method Resolution Order, MRO&#xff09;来确定的。MRO 是一个确定继承顺序的算法&#xff0c;它使用 C3 线性化算法来避免潜在的方法冲突。Python会根据继承顺序自动计算 MRO&#xff0c;我们只需要使用 supe…

人人都会的 Blazor —— 1.3 项目结构

项目结构 使用 Visual Studio 2022 创建 Blazor 项目。 在搜索框中输入【blazor】关键字,将列出以下已经存在的项目模板: Blazor Server App:基于 Blazor Server 托管模型的项目,并建立一些示例代码和组件;Blazor WebAssembly App:基于 Blazor WebAssembly 托管模型的项…

CSS 外边距、填充、分组嵌套、尺寸

一、CSS 外边距&#xff1a; CSS margin&#xff08;外边距&#xff09;属性定义元素周期的空间。margin清除周围的&#xff08;外边框&#xff09;元素区域。margin没有背景颜色&#xff0c;是完全透明的。margin可以单独改变元素的上、下、左、右边距&#xff0c;也可以一次改…

响应式招标投标网站模板源码带后台

模板信息&#xff1a; 模板编号&#xff1a;29165 模板编码&#xff1a;UTF8 模板分类&#xff1a;博客、文章、资讯、其他 适合行业&#xff1a;招标类企业 模板介绍&#xff1a; 本模板自带eyoucms内核&#xff0c;无需再下载eyou系统&#xff0c;原创设计、手工书写DIVCSS&a…

Python基础入门(5)----Python中的变量和表达式:变量的定义、赋值和数据类型转换

文章目录 Python中的变量和表达式:变量的定义、赋值和数据类型转换变量的定义变量的赋值数据类型转换注意事项表达式总结Python中的变量和表达式:变量的定义、赋值和数据类型转换 Python是一种高级编程语言,以其简洁明了的语法和强大的功能而闻名。在Python编程中,变量和表…

arcgis 批量删除Table中的某些Field

当shp或者table文件较少时&#xff0c;可以手动删除每个文件中的某些字段&#xff0c;当文件较多时&#xff0c;就需要使用arcpy或者model进行处理。

字节测试开发岗面试竟如此简单...

前言 因为读者里有不少刚入门测试的同学&#xff0c;这两天抽空整理了一份字节测试开发岗的面试题答案&#xff0c;说实话这个题目真挺简单的&#xff0c;如果你面大厂碰到此类面试题&#xff0c;也算是运气很好啦。大家也可以先自测一下&#xff0c;看看自己能不能答上来。 如…

图片文件过大怎么压缩?五种压缩方法大全

图片文件过大怎么压缩&#xff1f;不知道大家有没有遇到过这样的尴尬情况&#xff0c;当我们将一些图片上传到某个网站的时候&#xff0c;被提示图片大小操作了网站的限制而被禁止上传&#xff0c;我相信很多人都遇到过吧&#xff0c;其实这是网站的一张防御措施&#xff0c;防…

aosp定制android系统

目录 AOSP 准备工作(配置) 确定机型和版本 初始化 git安装 curl安装 同步源码 环境变量 创建aosp目录 指定同步版本 解下来安装编译需要的依赖 编译aosp源码 刷入系统 AOSP 全称 Android Open Source Project 是指Android开源项目&#xff0c;它是由Google主导的…

【Java】BMI身体质量指数计算工具

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍BMI身体质量指数计算工具的Java实现。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

服装和纺织品在欧盟和英国售卖需要做哪些认证?REACH认证、EN14682认证

近期&#xff0c;不少亚马逊卖家在欧洲和应该售卖纺织品和服装都遇到了安全问题&#xff0c;下架的理由都是不符合产品安全的要求&#xff0c;下架邮件有以下几种&#xff1a; ①标签不合规 ②不符合安全标准 那么&#xff0c;纺织品出口到欧盟和英国&#xff0c;具体有哪些要…

智能井盖传感器功能,万宾科技产品介绍

在国家治理方面&#xff0c;对社会的治理是一个重要的领域&#xff0c;一定要在推进社会治理现代化过程中提高市政府的管理和工作能力&#xff0c;推动社会拥有稳定有序的发展。在管理过程中对全市井盖进行统一化管理&#xff0c;可能是市政府比较头疼的难题&#xff0c;如果想…

新开普智慧校园系统RCE漏洞 [附POC]

文章目录 新开普智慧校园系统RCE漏洞 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 新开普智慧校园系统RCE漏洞 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#x…

某集团营销、制造多公司业财一体核算整体流程图(ODOO15/16)

某集团旗下有销售公司、加工制造厂、原料生产厂等多家公司&#xff0c;此类型公司从客户订单到完成交货&#xff0c;业务环节相对复杂&#xff0c;业务单据多&#xff0c;出纳银行收付款流水多、对象多&#xff0c;难以正确核销&#xff0c;跟单部难以全面了解订单进度&#xf…

【亲测推荐】魔方财务和魔方云系统开源全解密

简介 资源入口点击进入 众所周知&#xff0c;魔方财务现在官方售价299&#xff0c;那么接下来就是带来开心版&#xff0c;详细手写实测安装教程已经放在付费资源中 展示 > 本文由博客一文多发平台 [OpenWrite](https://openwrite.cn?fromarticle_bottom) 发布&#xff01;

大数据之LibrA数据库系统告警处理(ALM-12029 license文件失效)

告警解释 系统在安装集群后和每天零点检查当前系统中的license文件是否失效&#xff08;即当前集群中导入的license文件的节点数是否超限&#xff0c;license文件是否过期&#xff09;。如果license文件失效&#xff0c;产生该告警。 当license文件有效时&#xff0c;告警恢复…