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

SpringBoot實(shí)現(xiàn)消息推送的實(shí)戰(zhàn)(讓服務(wù)器學(xué)會"主動(dòng)搭訕")

 更新時(shí)間:2026年03月07日 10:56:25   作者:悟空碼字  
本文介紹了如何使用SSE技術(shù)實(shí)現(xiàn)SpringBoot應(yīng)用的消息推送,并提供了詳細(xì)的實(shí)戰(zhàn)步驟和優(yōu)化建議,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

想象一下這個(gè)場景:你的APP像個(gè)靦腆的男生,只會傻傻等著用戶來“敲門”(刷新頁面),而不知道主動(dòng)說“嘿,我有新消息給你!”這多尷尬啊!消息推送就像給服務(wù)器裝了社交牛逼癥,讓它能從幕后跳出來大喊:“注意!有熱乎的消息!”

一、推送技術(shù)選型:給服務(wù)器裝上“大喇叭”

SSE(Server-Sent Events) - 像單相思,服務(wù)器可以一直對客戶端叨叨叨,但客戶端只能聽著 WebSocket - 像熱戀中的情侶,雙方可以隨時(shí)互發(fā)消息 輪詢(Polling) - 像查崗的女朋友,隔幾秒就問一次“有新消息嗎?” 長輪詢(Long Polling) - 像有耐心的女朋友,等不到消息就不掛電話

今天咱們重點(diǎn)玩一下SSE,因?yàn)樗唵沃苯樱拖窠o服務(wù)器裝了個(gè)校園廣播站!

二、SpringBoot推送實(shí)戰(zhàn):三步搞定

第一步:添加依賴(給項(xiàng)目喂點(diǎn)“能量飲料”)

<!-- pom.xml -->
<dependencies>
    <!-- SpringBoot基礎(chǔ)套餐 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 給模板引擎加點(diǎn)料 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- 讓我們能處理異步請求 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
</dependencies>

第二步:創(chuàng)建SSE控制器(服務(wù)器的“播音室”)

package com.example.pushdemo.controller;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
@RestController
@RequestMapping("/sse")
public class SseController {
    // 保存所有連接的客戶端,CopyOnWriteArrayList是線程安全的
    private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>();
    /**
     * 客戶端連接入口 - 相當(dāng)于打開收音機(jī)
     * @return SseEmitter對象
     */
    @GetMapping(value = "/connect", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter connect() {
        // 設(shè)置連接超時(shí)時(shí)間(毫秒),0表示永不超時(shí)
        SseEmitter emitter = new SseEmitter(0L);
        // 連接建立時(shí)的處理
        emitter.onCompletion(() -> {
            System.out.println("客戶端斷開連接了,有點(diǎn)小失落...");
            emitters.remove(emitter);
        });
        emitter.onTimeout(() -> {
            System.out.println("客戶端連接超時(shí)了,是不是網(wǎng)不好?");
            emitters.remove(emitter);
        });
        // 添加到連接列表
        emitters.add(emitter);
        try {
            // 發(fā)送歡迎消息
            emitter.send(SseEmitter.event()
                    .name("welcome")  // 事件名稱
                    .data("連接成功!我是話癆服務(wù)器,我會主動(dòng)給你推送消息!"));
        } catch (IOException e) {
            emitter.completeWithError(e);
        }
        System.out.println("新客戶端加入,當(dāng)前連接數(shù):" + emitters.size());
        return emitter;
    }
    /**
     * 向所有客戶端廣播消息 - 服務(wù)器開始廣播啦!
     * @param message 要推送的消息
     * @return 推送結(jié)果
     */
    @PostMapping("/broadcast")
    public String broadcast(@RequestParam String message) {
        System.out.println("準(zhǔn)備廣播消息:" + message);
        int successCount = 0;
        // 遍歷所有連接
        for (SseEmitter emitter : emitters) {
            try {
                // 發(fā)送消息
                emitter.send(SseEmitter.event()
                        .name("message")  // 事件類型
                        .data(message + " - " + System.currentTimeMillis()));
                successCount++;
                System.out.println("消息已推送給客戶端:" + emitter);
            } catch (IOException e) {
                System.out.println("推送失敗,移除失效連接");
                emitters.remove(emitter);
            }
        }
        return String.format("廣播完成!成功推送給 %d/%d 個(gè)客戶端", 
                successCount, emitters.size());
    }
    /**
     * 發(fā)送系統(tǒng)通知
     */
    @PostMapping("/system-notice")
    public String sendSystemNotice(@RequestParam String notice) {
        for (SseEmitter emitter : emitters) {
            try {
                emitter.send(SseEmitter.event()
                        .name("system")
                        .data("系統(tǒng)通知:" + notice));
            } catch (IOException e) {
                // 靜默處理錯(cuò)誤連接
            }
        }
        return "系統(tǒng)通知已發(fā)送";
    }
}

第三步:創(chuàng)建WebSocket配置(備選方案,雙向通信)

package com.example.pushdemo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new MyWebSocketHandler(), "/ws")
                .setAllowedOrigins("*");  // 生產(chǎn)環(huán)境記得限制域名哦!
    }
}
package com.example.pushdemo.config;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
public class MyWebSocketHandler extends TextWebSocketHandler {
    private static final CopyOnWriteArraySet<WebSocketSession> sessions = 
            new CopyOnWriteArraySet<>();
    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        sessions.add(session);
        System.out.println("WebSocket連接建立,當(dāng)前連接數(shù):" + sessions.size());
        try {
            session.sendMessage(new TextMessage("?? 歡迎來到WebSocket聊天室!"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    protected void handleTextMessage(WebSocketSession session, 
            TextMessage message) throws Exception {
        // 廣播收到的消息
        String payload = message.getPayload();
        System.out.println("收到消息:" + payload);
        for (WebSocketSession s : sessions) {
            if (s.isOpen()) {
                s.sendMessage(new TextMessage("用戶說:" + payload));
            }
        }
    }
    @Override
    public void afterConnectionClosed(WebSocketSession session, 
            org.springframework.web.socket.CloseStatus status) {
        sessions.remove(session);
        System.out.println("WebSocket連接關(guān)閉");
    }
}

第四步:創(chuàng)建HTML測試頁面(給客戶端配個(gè)"收音機(jī)")

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>消息推送測試 - 服務(wù)器的碎碎念</title>
    <style>
        body {
            font-family: 'Microsoft YaHei', sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
        }
        .container {
            background: white;
            border-radius: 15px;
            padding: 30px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.1);
        }
        h1 {
            color: #2c3e50;
            text-align: center;
            margin-bottom: 30px;
        }
        .card {
            background: #f8f9fa;
            border-radius: 10px;
            padding: 20px;
            margin: 20px 0;
            border-left: 5px solid #3498db;
        }
        .message-area {
            height: 300px;
            overflow-y: auto;
            border: 1px solid #ddd;
            border-radius: 8px;
            padding: 15px;
            margin: 20px 0;
            background: #fff;
        }
        .message {
            padding: 10px;
            margin: 10px 0;
            border-radius: 8px;
            animation: fadeIn 0.5s;
        }
        .system { background: #e3f2fd; }
        .welcome { background: #e8f5e9; }
        .user { background: #fff3e0; }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
        button {
            background: #3498db;
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 16px;
            transition: all 0.3s;
            margin: 5px;
        }
        button:hover {
            background: #2980b9;
            transform: translateY(-2px);
        }
        .btn-danger {
            background: #e74c3c;
        }
        .btn-success {
            background: #2ecc71;
        }
        .input-group {
            display: flex;
            gap: 10px;
            margin: 20px 0;
        }
        input {
            flex: 1;
            padding: 12px;
            border: 2px solid #ddd;
            border-radius: 6px;
            font-size: 16px;
        }
        input:focus {
            border-color: #3498db;
            outline: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>服務(wù)器廣播站測試</h1>
        <div class="card">
            <h3>連接狀態(tài)</h3>
            <p id="status">準(zhǔn)備連接服務(wù)器...</p>
            <button onclick="connectSSE()">連接SSE服務(wù)器</button>
            <button onclick="connectWebSocket()">連接WebSocket</button>
            <button class="btn-danger" onclick="disconnect()">斷開連接</button>
        </div>
        <div class="card">
            <h3>消息測試</h3>
            <div class="input-group">
                <input type="text" id="messageInput" 
                       placeholder="輸入要廣播的消息..." />
                <button onclick="sendBroadcast()">廣播消息</button>
                <button class="btn-success" onclick="sendSystemNotice()">
                    發(fā)送系統(tǒng)通知
                </button>
            </div>
        </div>
        <div class="card">
            <h3>收到的消息</h3>
            <div id="messageArea" class="message-area"></div>
            <button onclick="clearMessages()">清空消息</button>
            <span id="counter">消息數(shù)量: 0</span>
        </div>
    </div>
    <script>
        let eventSource = null;
        let ws = null;
        let messageCount = 0;
        // 添加消息到顯示區(qū)域
        function addMessage(content, type = 'system') {
            const area = document.getElementById('messageArea');
            const message = document.createElement('div');
            message.className = `message ${type}`;
            message.innerHTML = `
                <strong>[${new Date().toLocaleTimeString()}]</strong>
                <span>${content}</span>
            `;
            area.appendChild(message);
            area.scrollTop = area.scrollHeight;
            messageCount++;
            document.getElementById('counter').textContent = 
                `消息數(shù)量: ${messageCount}`;
        }
        // 連接SSE
        function connectSSE() {
            if (eventSource) {
                addMessage('已經(jīng)連接過了,別著急嘛!');
                return;
            }
            eventSource = new EventSource('/sse/connect');
            eventSource.onopen = () => {
                document.getElementById('status').innerHTML = 
                    'SSE連接成功!服務(wù)器現(xiàn)在可以主動(dòng)推送消息了';
                addMessage('SSE連接已建立', 'welcome');
            };
            // 監(jiān)聽不同類型的消息
            eventSource.addEventListener('welcome', (e) => {
                addMessage(e.data, 'welcome');
            });
            eventSource.addEventListener('message', (e) => {
                addMessage(`收到廣播: ${e.data}`, 'user');
            });
            eventSource.addEventListener('system', (e) => {
                addMessage(e.data, 'system');
            });
            eventSource.onerror = (e) => {
                document.getElementById('status').innerHTML = 
                    'SSE連接出錯(cuò),嘗試重連中...';
                console.error('SSE錯(cuò)誤:', e);
                // 3秒后重連
                setTimeout(() => {
                    if (eventSource.readyState === EventSource.CLOSED) {
                        disconnect();
                        connectSSE();
                    }
                }, 3000);
            };
        }
        // 連接WebSocket
        function connectWebSocket() {
            if (ws && ws.readyState === WebSocket.OPEN) {
                addMessage('WebSocket已經(jīng)連接了!');
                return;
            }
            const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
            const host = window.location.host;
            ws = new WebSocket(`${protocol}//${host}/ws`);
            ws.onopen = () => {
                document.getElementById('status').innerHTML = 
                    'WebSocket連接成功!可以雙向通信了';
                addMessage('WebSocket連接已建立', 'welcome');
            };
            ws.onmessage = (e) => {
                addMessage(`WebSocket消息: ${e.data}`, 'user');
            };
            ws.onerror = (e) => {
                addMessage('WebSocket連接錯(cuò)誤', 'system');
            };
            ws.onclose = () => {
                document.getElementById('status').innerHTML = 
                    'WebSocket連接已關(guān)閉';
            };
        }
        // 發(fā)送廣播消息
        async function sendBroadcast() {
            const input = document.getElementById('messageInput');
            const message = input.value.trim();
            if (!message) {
                addMessage('請輸入要發(fā)送的消息!', 'system');
                return;
            }
            try {
                const response = await fetch('/sse/broadcast', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                    body: `message=${encodeURIComponent(message)}`
                });
                const result = await response.text();
                addMessage(`${result}`, 'system');
                input.value = '';
            } catch (error) {
                addMessage('發(fā)送失敗: ' + error, 'system');
            }
        }
        // 發(fā)送系統(tǒng)通知
        async function sendSystemNotice() {
            const notice = prompt('請輸入系統(tǒng)通知內(nèi)容:', '服務(wù)器即將維護(hù)');
            if (!notice) return;
            try {
                const response = await fetch(`/sse/system-notice?notice=${encodeURIComponent(notice)}`, {
                    method: 'POST'
                });
                const result = await response.text();
                addMessage(`${result}`, 'system');
            } catch (error) {
                addMessage('發(fā)送系統(tǒng)通知失敗', 'system');
            }
        }
        // 斷開連接
        function disconnect() {
            if (eventSource) {
                eventSource.close();
                eventSource = null;
                addMessage('SSE連接已關(guān)閉', 'system');
            }
            if (ws) {
                ws.close();
                ws = null;
                addMessage('WebSocket連接已關(guān)閉', 'system');
            }
            document.getElementById('status').innerHTML = 
                '連接已斷開';
        }
        // 清空消息
        function clearMessages() {
            document.getElementById('messageArea').innerHTML = '';
            messageCount = 0;
            document.getElementById('counter').textContent = '消息數(shù)量: 0';
            addMessage('消息已清空', 'system');
        }
        // 頁面加載時(shí)的小動(dòng)畫
        window.onload = () => {
            addMessage('消息推送演示系統(tǒng)已啟動(dòng)', 'welcome');
            addMessage('試試點(diǎn)擊"連接SSE服務(wù)器"按鈕開始體驗(yàn)吧!', 'system');
        };
        // 監(jiān)聽鍵盤事件
        document.getElementById('messageInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                sendBroadcast();
            }
        });
    </script>
</body>
</html>

三、進(jìn)階優(yōu)化:讓推送更"聰明"

1. 連接管理器(專業(yè)版)

@Component
public class ConnectionManager {
    private final Map<String, SseEmitter> userConnections = 
            new ConcurrentHashMap<>();
    private final Map<String, String> connectionUserMap = 
            new ConcurrentHashMap<>();
    /**
     * 添加用戶連接
     */
    public SseEmitter addConnection(String userId) {
        // 移除舊連接(避免重復(fù)登錄)
        if (userConnections.containsKey(userId)) {
            userConnections.get(userId).complete();
        }
        SseEmitter emitter = new SseEmitter(30 * 60 * 1000L); // 30分鐘超時(shí)
        emitter.onCompletion(() -> removeConnection(userId));
        emitter.onTimeout(() -> removeConnection(userId));
        userConnections.put(userId, emitter);
        // 發(fā)送連接成功消息
        try {
            emitter.send(SseEmitter.event()
                    .name("connected")
                    .data("用戶 " + userId + " 連接成功!"));
        } catch (IOException e) {
            removeConnection(userId);
        }
        return emitter;
    }
    /**
     * 向指定用戶推送消息
     */
    public void pushToUser(String userId, String message) {
        SseEmitter emitter = userConnections.get(userId);
        if (emitter != null) {
            try {
                emitter.send(SseEmitter.event()
                        .data(message));
            } catch (IOException e) {
                removeConnection(userId);
            }
        }
    }
    /**
     * 向所有用戶廣播
     */
    public void broadcast(String message) {
        userConnections.forEach((userId, emitter) -> {
            try {
                emitter.send(SseEmitter.event()
                        .data(message));
            } catch (IOException e) {
                removeConnection(userId);
            }
        });
    }
    private void removeConnection(String userId) {
        userConnections.remove(userId);
        System.out.println("用戶 " + userId + " 的連接已移除");
    }
}

2. 心跳檢測(保持連接活躍)

@Component
public class HeartbeatScheduler {
    @Autowired
    private ConnectionManager connectionManager;
    @Scheduled(fixedRate = 25000) // 每25秒發(fā)送一次心跳
    public void sendHeartbeat() {
        connectionManager.broadcast("心跳檢測 - " + new Date());
    }
}

四、不同方案的對比總結(jié)

方案優(yōu)點(diǎn)缺點(diǎn)適用場景
SSE簡單易用、自動(dòng)重連、HTTP協(xié)議友好只能服務(wù)器到客戶端單向實(shí)時(shí)通知、新聞推送、股票行情
WebSocket雙向通信、實(shí)時(shí)性最好實(shí)現(xiàn)復(fù)雜、需要額外協(xié)議聊天室、在線游戲、協(xié)同編輯
長輪詢兼容性好、實(shí)現(xiàn)簡單延遲高、服務(wù)器壓力大兼容性要求高的老系統(tǒng)
短輪詢極其簡單、無狀態(tài)實(shí)時(shí)性差、資源浪費(fèi)更新頻率低的應(yīng)用

五、總結(jié):讓服務(wù)器"開口說話"的藝術(shù)

通過這次探索,我們給SpringBoot服務(wù)器裝上了"嘴巴",讓它學(xué)會了主動(dòng)和客戶端聊天!總結(jié)一下關(guān)鍵點(diǎn):

  1. SSE是你的好朋友 - 對于服務(wù)器向客戶端的單向推送,SSE簡單到讓人感動(dòng)
  2. 連接管理很重要 - 記得及時(shí)清理斷開的連接,不然服務(wù)器內(nèi)存會"爆炸"
  3. 錯(cuò)誤處理不能忘 - 網(wǎng)絡(luò)世界充滿了不確定性,要優(yōu)雅地處理各種異常
  4. 心跳檢測保活力 - 定期發(fā)送心跳,防止連接被防火墻誤殺
  5. 生產(chǎn)環(huán)境要優(yōu)化 - 記得添加認(rèn)證、限流、集群支持等

推送消息就像談戀愛,不能太頻繁(用戶會煩),也不能太冷淡(用戶會跑),要掌握好節(jié)奏!而且千萬別"已讀不回",那比不推送還糟糕!

現(xiàn)在,你的服務(wù)器已經(jīng)從"悶葫蘆"變成了"社交達(dá)人",快去讓它和客戶端愉快地聊天吧!記?。汉玫耐扑拖到y(tǒng),應(yīng)該是用戶感覺不到它的存在,但需要時(shí)它永遠(yuǎn)在那里!

如果你想讓推送更有趣,可以添加表情包識別、消息優(yōu)先級、智能推送時(shí)間等功能。畢竟,誰不喜歡一個(gè)會"察言觀色"的服務(wù)器呢?

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)消息推送:讓服務(wù)器學(xué)會“主動(dòng)搭訕”的文章就介紹到這了,更多相關(guān)springboot消息推送內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringCloud聲明式Feign客戶端調(diào)用工具使用

    SpringCloud聲明式Feign客戶端調(diào)用工具使用

    這篇文章主要為大家介紹了SpringCloud聲明式Feign客戶端調(diào)用工具使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • spring BeanProcessor接口詳解

    spring BeanProcessor接口詳解

    這篇文章主要介紹了spring BeanProcessor接口的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用spring,感興趣的朋友可以了解下
    2021-03-03
  • Java使用java -jar啟動(dòng)并按日分包日志的最佳實(shí)踐

    Java使用java -jar啟動(dòng)并按日分包日志的最佳實(shí)踐

    在生產(chǎn)環(huán)境中,Java應(yīng)用程序通常以java -jar方式運(yùn)行,而日志管理是運(yùn)維的重要部分,如果日志文件過大,不僅影響性能,還會增加排查問題的難度,因此,按日分包日志成為常見的需求,本文將介紹4種實(shí)現(xiàn)方式,并提供詳細(xì)配置和代碼示例,需要的朋友可以參考下
    2025-07-07
  • SpringBoot項(xiàng)目中報(bào)錯(cuò)The field screenShot exceeds its maximum permitted size of 1048576 bytes.的問題及解決

    SpringBoot項(xiàng)目中報(bào)錯(cuò)The field screenShot exceeds&n

    這篇文章主要介紹了SpringBoot項(xiàng)目中報(bào)錯(cuò)The field screenShot exceeds its maximum permitted size of 1048576 bytes.的問題及解決,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Java中Stream API處理Map初始化的操作方法

    Java中Stream API處理Map初始化的操作方法

    Stream API提供了多種方式來實(shí)現(xiàn)Map的構(gòu)建、存在則更新、不存在則添加的操作,本文通過實(shí)例代碼介紹Java中Stream API處理Map初始化的操作方法,感興趣的朋友一起看看吧
    2025-10-10
  • springboot3.x使用@NacosValue無法獲取配置信息的解決過程

    springboot3.x使用@NacosValue無法獲取配置信息的解決過程

    在Spring Boot 3.x中升級Nacos依賴后,使用@NacosValue無法動(dòng)態(tài)獲取配置,通過引入Spring Cloud依賴和使用@RefreshScope@Value結(jié)合的方式解決了問題
    2025-12-12
  • Java SE實(shí)現(xiàn)多人聊天室功能

    Java SE實(shí)現(xiàn)多人聊天室功能

    這篇文章主要為大家詳細(xì)介紹了Java SE實(shí)現(xiàn)多人聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • SpringBoot之RabbitMQ的使用方法

    SpringBoot之RabbitMQ的使用方法

    這篇文章主要介紹了SpringBoot之RabbitMQ的使用方法,詳細(xì)的介紹了2種模式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • @Accessors(chain = true)注解報(bào)錯(cuò)的解決方案

    @Accessors(chain = true)注解報(bào)錯(cuò)的解決方案

    這篇文章主要介紹了@Accessors(chain = true)注解報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Spring-AOP 靜態(tài)正則表達(dá)式方法如何匹配切面

    Spring-AOP 靜態(tài)正則表達(dá)式方法如何匹配切面

    這篇文章主要介紹了Spring-AOP 靜態(tài)正則表達(dá)式方法如何匹配切面的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評論

神农架林区| 盐亭县| 得荣县| 巨野县| 清水河县| 五莲县| 许昌市| 炉霍县| 从江县| 汉寿县| 沂南县| 辰溪县| 藁城市| 大新县| 杭锦旗| 南川市| 肇庆市| 曲阳县| 祁门县| 沙田区| 广丰县| 红河县| 新干县| 临武县| 新平| 珲春市| 乐平市| 修武县| 广水市| 阳西县| 信丰县| 南京市| 栖霞市| 南靖县| 舒城县| 赞皇县| 沙河市| 巴南区| 赣榆县| 册亨县| 长葛市|