最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決@ServerEndpoint不能注入@Autowired的問(wèn)題

 更新時(shí)間:2024年05月21日 09:44:04   作者:于小袁  
這篇文章主要介紹了解決@ServerEndpoint不能注入@Autowired的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

都會(huì)報(bào)空指針錯(cuò)誤的原因

本質(zhì)原因

spring管理的都是單例(singleton)和 websocket (多對(duì)象)相沖突。

?因?yàn)閃ebSocket 是一個(gè)多例,因?yàn)槟阈枰鄠€(gè)對(duì)象來(lái)保存鏈接,所以就和單例無(wú)緣了,然而我們交給Spring管理的是單例的東西,那么我們可以從這里知道,WebSocket的對(duì)象是不能交給Spring管理的

此時(shí)我們有兩種解決方案;

方案1: 在上下文獲取你需要的對(duì)象

package cn.jiabao.util;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Repository;

@Repository
public class SpringUtils implements BeanFactoryPostProcessor {

    //Spring應(yīng)用上下文環(huán)境
    private static ConfigurableListableBeanFactory beanFactory;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        SpringUtils.beanFactory = beanFactory;
    }

    public static ConfigurableListableBeanFactory getBeanFactory() {
        return beanFactory;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) throws BeansException {
        return (T) getBeanFactory().getBean(name);
    }

    public static <T> T
    getBean(Class<T> clz) throws BeansException {
        T result = (T) getBeanFactory().getBean(clz);
        return result;
    }
}

--------------------------------------------------------
 private StringRedisTemplate stringRedisTemplate = SpringUtils.getBean(StringRedisTemplate.class);

    @OnOpen
    public void OnOpen(Session session, @PathParam(value = "name") String name,@PathParam(value = "password") String password) {
        stringRedisTemplate.opsForValue().set("1","1");

        this.session = session;
        this.name = name;
        // name是用來(lái)表示唯一客戶(hù)端,如果需要指定發(fā)送,需要指定發(fā)送通過(guò)name來(lái)區(qū)分
        webSocketSet.put(name, this);
        log.info("[WebSocket] 連接成功,當(dāng)前連接人數(shù)為:={}", webSocketSet.size());
        //接收用戶(hù)傳入的參數(shù),并且進(jìn)行判斷登錄是否成功 如果登錄成功那    personService.savePersonSql(name,password);么 就保存Sesion 并且  鏈接成功 否職反之

         //    personService.savePersonSql(name,"1"); //多例之后 可以執(zhí)行reids代碼等等
        // 注意: 不能在這里面直接用Reids 即使多例 直接保存也有問(wèn)題
    }

使用上面的工具類(lèi)就,可以從上下文獲取到你需要的實(shí)例對(duì)象

方案2: 既然不給那我就自己搞一個(gè)注入進(jìn)去

private static StringRedisTemplate stringRedisTemplate;
@Autowired
private void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate){
    Link.stringRedisTemplate =stringRedisTemplate;
}

心得

? 這里L(fēng)ink的多對(duì)象機(jī)制和Spring 的controller注解截止可以同時(shí)進(jìn)行,互相沒(méi)有矛盾。

Spring在初始的時(shí)候,創(chuàng)建一個(gè)Link的對(duì)象,該對(duì)象在運(yùn)行期間不會(huì)被使用,同時(shí)注入的類(lèi)進(jìn)行了靜態(tài)的完善,這是Spring在這套代碼里面的唯一作用,當(dāng)有用戶(hù)聊天的時(shí)候,java會(huì)根據(jù)Link類(lèi)創(chuàng)建對(duì)象,每個(gè)對(duì)象保持對(duì)應(yīng)的用戶(hù)鏈接,因?yàn)殪o態(tài)類(lèi)已經(jīng)在啟動(dòng)的時(shí)候被Spring初始化了,所以此時(shí)每個(gè)對(duì)象都可以被正常訪問(wèn)

注意:

@Component 這個(gè)注解需要有,不然就不能被加載到Spring 就不能在啟動(dòng)服務(wù)器的時(shí)候進(jìn)行正常的鏈接

package cn.jiabao.link;
import cn.jiabao.util.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@ServerEndpoint("/websocket/{name}/{password}")
@Component
@Controller
public class Link {

    private static StringRedisTemplate stringRedisTemplate;
    @Autowired
    private void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate){
        Link.stringRedisTemplate =stringRedisTemplate;
    }

    /**
     * 與某個(gè)客戶(hù)端的連接對(duì)話(huà),需要通過(guò)它來(lái)給客戶(hù)端發(fā)送消息
     */
    private Session session;

    /**
     * 標(biāo)識(shí)當(dāng)前連接客戶(hù)端的用戶(hù)名
     */
    private String name;

    /**
     * 用于存所有的連接服務(wù)的客戶(hù)端,這個(gè)對(duì)象存儲(chǔ)是安全的
     */
    private static ConcurrentHashMap<String, Link> webSocketSet = new ConcurrentHashMap<>();


 //    private StringRedisTemplate stringRedisTemplate = SpringUtils.getBean(StringRedisTemplate.class);

    @OnOpen
    public void OnOpen(Session session, @PathParam(value = "name") String name,@PathParam(value = "password") String password) {
        stringRedisTemplate.opsForValue().set("1","1");

        this.session = session;
        this.name = name;
        // name是用來(lái)表示唯一客戶(hù)端,如果需要指定發(fā)送,需要指定發(fā)送通過(guò)name來(lái)區(qū)分
        webSocketSet.put(name, this);
        log.info("[WebSocket] 連接成功,當(dāng)前連接人數(shù)為:={}", webSocketSet.size());
        //接收用戶(hù)傳入的參數(shù),并且進(jìn)行判斷登錄是否成功 如果登錄成功那    personService.savePersonSql(name,password);么 就保存Sesion 并且  鏈接成功 否職反之

         //    personService.savePersonSql(name,"1"); //多例之后 可以執(zhí)行reids代碼等等
        // 注意: 不能在這里面直接用Reids 即使多例 直接保存也有問(wèn)題
    }

    @OnMessage
    public void OnMessage(String message) {
        log.info("[WebSocket] 收到消息:{}", message);
        //判斷是否需要指定發(fā)送,具體規(guī)則自定義
        if (message.indexOf("TOUSER") == 0) {
            String name = message.substring(message.indexOf("TOUSER") + 6, message.indexOf(";"));
            AppointSending(name, message.substring(message.indexOf(";") + 1, message.length()));
        } else {
            GroupSending(message);
        }
    }


    /**
     * 群發(fā)
     *
     * @param message
     */
    public void GroupSending(String message) {
        for (String name : webSocketSet.keySet()) {
            try {
                webSocketSet.get(name).session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 指定發(fā)送
     *
     * @param name
     * @param message
     */
    public void AppointSending(String name, String message) {
        try {
            webSocketSet.get(name).session.getBasicRemote().sendText(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Link getPerson(String key) {
        return webSocketSet.get(key);
    }

    public static ConcurrentHashMap<String, cn.jiabao.link.Link> getMap() {
        return webSocketSet;
    }

}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Java的Struts框架中注釋的用法

    詳解Java的Struts框架中注釋的用法

    這篇文章主要介紹了詳解Java的Struts框架中注釋的用法,Struts是Java的SSH三大web開(kāi)發(fā)框架之一,需要的朋友可以參考下
    2015-12-12
  • Java中的浮點(diǎn)數(shù)分析

    Java中的浮點(diǎn)數(shù)分析

    Java中的浮點(diǎn)數(shù)分析...
    2006-12-12
  • JAVA 泛型與通配符詳解從原理到實(shí)戰(zhàn)應(yīng)用

    JAVA 泛型與通配符詳解從原理到實(shí)戰(zhàn)應(yīng)用

    本章全面介紹了泛型的核心概念、設(shè)計(jì)初衷及三大使用方式(泛型類(lèi)、泛型接口、泛型方法),重點(diǎn)講解了泛型的擦除機(jī)制和通配符的靈活運(yùn)用,強(qiáng)調(diào)了泛型在編譯期類(lèi)型安全和運(yùn)行時(shí)類(lèi)型擦除的優(yōu)勢(shì),感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • Java超詳細(xì)講解抽象類(lèi)的原理與用法

    Java超詳細(xì)講解抽象類(lèi)的原理與用法

    對(duì)于面向?qū)ο缶幊虂?lái)說(shuō),抽象是它的一大特征之一,在Java中可以通過(guò)兩種形式來(lái)體現(xiàn)OOP的抽象:接口和抽象類(lèi),下面這篇文章主要給大家介紹了關(guān)于Java抽象類(lèi)相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • SpringCloud與Consul集成實(shí)現(xiàn)負(fù)載均衡功能

    SpringCloud與Consul集成實(shí)現(xiàn)負(fù)載均衡功能

    負(fù)載均衡基本概念有:實(shí)服務(wù)、實(shí)服務(wù)組、虛服務(wù)、調(diào)度算法、持續(xù)性等,其常用應(yīng)用場(chǎng)景主要是服務(wù)器負(fù)載均衡,鏈路負(fù)載均衡。這篇文章主要介紹了SpringCloud與Consul集成實(shí)現(xiàn)負(fù)載均衡 ,需要的朋友可以參考下
    2018-09-09
  • Spring?Cloud?Ribbon?負(fù)載均衡使用策略示例詳解

    Spring?Cloud?Ribbon?負(fù)載均衡使用策略示例詳解

    Spring?Cloud?Ribbon?是基于Netflix?Ribbon?實(shí)現(xiàn)的一套客戶(hù)端負(fù)載均衡工具,Ribbon客戶(hù)端組件提供了一系列的完善的配置,如超時(shí),重試等,這篇文章主要介紹了Spring?Cloud?Ribbon?負(fù)載均衡使用策略示例詳解,需要的朋友可以參考下
    2023-03-03
  • 使用Java連接WMI獲取系統(tǒng)信息的方法

    使用Java連接WMI獲取系統(tǒng)信息的方法

    在 Windows 系統(tǒng)上,WMI是一套管理數(shù)據(jù)和操作系統(tǒng)組件的基礎(chǔ)設(shè)施,能讓?xiě)?yīng)用程序查詢(xún)系統(tǒng)信息、監(jiān)控硬件狀態(tài)以及管理系統(tǒng)配置,本項(xiàng)目旨在講解如何通過(guò) Java 連接 WMI 獲取系統(tǒng)信息,需要的朋友可以參考下
    2025-03-03
  • java中使用logger打印日志有哪些坑

    java中使用logger打印日志有哪些坑

    在Java中使用日志記錄器(Logger)打印日志時(shí),確實(shí)存在一些常見(jiàn)的坑需要注意,本文就來(lái)介紹一下幾種方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • Maven打jar包的三種方式(小結(jié))

    Maven打jar包的三種方式(小結(jié))

    這篇文章主要介紹了Maven打jar包的三種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請(qǐng)求數(shù)據(jù)丟失問(wèn)題

    解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請(qǐng)求數(shù)據(jù)丟失問(wèn)題

    這篇文章主要介紹了解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請(qǐng)求數(shù)據(jù)丟失問(wèn)題,主要包括無(wú)異步線程得情況下feign遠(yuǎn)程調(diào)用,異步情況下丟失上下文問(wèn)題,需要的朋友可以參考下
    2022-05-05

最新評(píng)論

邢台县| 江源县| 白银市| 土默特右旗| 祁东县| 施秉县| 外汇| 阿城市| 客服| 淳化县| 长治市| 正宁县| 龙州县| 丰台区| 如皋市| 邹平县| 临城县| 准格尔旗| 措勤县| 措勤县| 阿克苏市| 绥芬河市| 宣汉县| 双柏县| 高碑店市| 贡觉县| 会同县| 泸水县| 长武县| 平乐县| 中卫市| 英超| 边坝县| 阳谷县| 禹城市| 资源县| 和顺县| 南澳县| 阳高县| 会昌县| 临沂市|