成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何使用 CGLIB 在 Spring Boot 3.3 中實現動態代理

開發 前端
本文詳細介紹了如何在 Spring Boot 3.3 中使用 CGLIB 實現動態代理。通過實際的代碼示例,展示了 CGLIB 在動態代理中的應用,以及如何在 Spring Boot 項目中集成 CGLIB。

在 Java 開發中,代理模式是一種重要的設計模式,通過代理對象來控制對目標對象的訪問。代理模式在 AOP(面向切面編程)中得到了廣泛應用,尤其是在 Spring 框架中。Spring 提供了兩種主要的代理機制:JDK 動態代理和 CGLIB 動態代理。其中,JDK 動態代理僅能代理實現了接口的類,而 CGLIB 動態代理則沒有這一限制,可以代理任何普通的類。因此,CGLIB 動態代理在實際開發中非常實用,特別是在需要代理沒有實現接口的類時。

本文將深入探討如何在 Spring Boot 3.3 中使用 CGLIB 實現動態代理。我們將通過具體的代碼示例,展示如何在應用程序中集成 CGLIB,并解釋其在 AOP 編程中的應用場景和優勢。同時,我們還將展示如何通過前后端協作,將代理后的效果展示在 Web 頁面上,從而幫助開發者更好地理解和運用 CGLIB 動態代理。

CGLIB 簡介

CGLIB(Code Generation Library)是一個強大的高性能代碼生成庫,主要用于在運行時動態生成類和代理對象。CGLIB 通過使用底層的 ASM 字節碼操縱框架,直接操作字節碼文件,生成新的類或增強現有的類。與 JDK 動態代理不同,CGLIB 不需要目標類實現任何接口,這使得它在處理代理普通類時顯得非常靈活和強大。

CGLIB 動態代理的工作原理是通過生成目標類的子類,并在子類中重寫目標類的方法來實現對方法調用的攔截。CGLIB 可以在方法調用的前后添加自定義邏輯,例如日志記錄、性能監控、事務管理等。這使得它在實現 AOP 編程時具有極大的優勢,尤其是在 Spring 框架中被廣泛應用。

值得注意的是,由于 CGLIB 是通過繼承的方式實現代理,因此目標類不能是 final 的,否則會導致代理失敗。此外,目標類中的 final 方法也無法被代理,因為 final 方法不能被重寫。

運行效果:

圖片圖片

若想獲取項目完整代碼以及其他文章的項目源碼,且在代碼編寫時遇到問題需要咨詢交流,歡迎加入下方的知識星球。

項目結構

在開始之前,我們需要設置一個 Spring Boot 3.3 項目。項目結構如下:

cglib-demo
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── icoderoad
│   │   │           └── cglib
│   │   │               ├── service
│   │   │               │   └── CglibDemoService.java
│   │   │               ├── proxy
│   │   │               │   └── CglibProxy.java
│   │   │               └── CglibDemoApplication.java
│   │   └── resources
│   │       ├── application.yaml
│   │       └── templates
│   │           └── index.html
└── pom.xml

配置文件

pom.xml 配置

首先,在 pom.xml 文件中引入必要的依賴:

<?xml versinotallow="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.3.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.icoderoad</groupId>
	<artifactId>cglib-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>cglib-demo</name>
	<description>Demo project for Spring Boot</description>
	
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<!-- Spring Boot Starter Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Boot Thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- CGLIB Dependency -->
        <dependency>
		    <groupId>cglib</groupId>
		    <artifactId>cglib-nodep</artifactId>
		    <version>3.3.0</version> <!-- 或者更高的版本 -->
		</dependency>

        <!-- Bootstrap CSS -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>5.3.0</version>
        </dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

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

</project>
application.yaml 配置

在 src/main/resources/application.yaml 文件中,我們可以加入一些簡單的配置:

server:
  port: 8080

spring:
  thymeleaf:
    cache: false

CGLIB 動態代理實現

創建一個簡單的服務類

首先,我們創建一個服務類 CglibDemoService,這個類將被代理:

package com.icoderoad.cglib_demo.service;

public class CglibDemoService {

    public String sayHello(String name) {
        return "你好, " + name;
    }

    public String sayGoodbye(String name) {
        return "再見, " + name;
    }
}
創建 CGLIB 代理類

接下來,我們創建一個 CGLIB 代理類 CglibProxy,用于攔截方法調用并進行處理:

package com.icoderoad.cglib_demo.proxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor {

    // 被代理的目標對象
    private final Object target;

    // 構造方法,傳入目標對象
    public CglibProxy(Object target) {
        this.target = target;
    }

    // 攔截方法,在目標方法執行前后加入自定義邏輯
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("方法執行前: " + method.getName());
        Object result = proxy.invoke(target, args);
        System.out.println("方法執行后: " + method.getName());
        return result;
    }

    // 獲取代理對象
    public Object getProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
}
使用代理類

在應用的啟動類中,我們將使用 CglibProxy 來代理 CglibDemoService:

package com.icoderoad.cglib_demo;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.icoderoad.cglib_demo.proxy.CglibProxy;
import com.icoderoad.cglib_demo.service.CglibDemoService;

@SpringBootApplication
public class CglibDemoApplication implements CommandLineRunner {

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

    @Override
    public void run(String... args) throws Exception {
        CglibDemoService targetService = new CglibDemoService();
        CglibProxy proxy = new CglibProxy(targetService);
        CglibDemoService proxyService = (CglibDemoService) proxy.getProxy();
        
        // 調用代理對象的方法
        System.out.println(proxyService.sayHello("小明"));
        System.out.println(proxyService.sayGoodbye("小明"));
    }
}

在這個例子中,我們通過 CglibProxy 代理 CglibDemoService,并在方法調用前后添加了自定義邏輯。

后端控制器

為了將數據傳遞到前端頁面,我們需要創建一個控制器:

package com.icoderoad.cglib_demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import com.icoderoad.cglib_demo.proxy.CglibProxy;
import com.icoderoad.cglib_demo.service.CglibDemoService;

@Controller
public class DemoController {

    @GetMapping("/")
    public String index(Model model) {
        // 創建目標對象
        CglibDemoService demoService = new CglibDemoService();
        // 創建代理對象
        CglibProxy proxy = new CglibProxy(demoService);
        CglibDemoService proxyService = (CglibDemoService) proxy.getProxy();

        // 將方法調用結果傳遞給前端頁面
        model.addAttribute("helloMessage", proxyService.sayHello("路條編程"));
        model.addAttribute("goodbyeMessage", proxyService.sayGoodbye("路條編程"));
        return "index";
    }
}

前端頁面展示

Thymeleaf 模板

在 src/main/resources/templates/index.html 文件中,創建一個簡單的前端頁面:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>CGLIB 代理演示</title>
    <link rel="stylesheet" th:href="@{/webjars/bootstrap/5.3.0/css/bootstrap.min.css}">
</head>
<body>
<div class="container">
    <h1>CGLIB 代理演示</h1>
    <p th:text="'歡迎消息: ' + ${helloMessage}"></p>
    <p th:text="'告別消息: ' + ${goodbyeMessage}"></p>
</div>
<script th:src="@{/webjars/bootstrap/5.3.0/js/bootstrap.bundle.min.js}"></script>
</body>
</html>

使用 --add-opens JVM 參數

在啟動你的應用時,添加 --add-opens 參數以允許訪問被封閉的模塊:

java --add-opens java.base/java.lang=ALL-UNNAMED -jar your-application.jar

如果你是在 IDE 中運行應用程序,可以在 IDE 的運行配置中添加這個參數。

在 Eclipse 中配置 JVM 參數來解決 CGLIB 與 Java 模塊系統兼容性問題,可以按照以下步驟操作:

配置 JVM 參數

  1. 打開 Eclipse 項目屬性
  • 在 Eclipse 中,右鍵點擊你的項目,選擇 Properties(屬性)。
  1. 進入 Run/Debug Settings
  • 在左側面板中,選擇 Run/Debug Settings。

  1. 選擇或創建運行配置

  • 如果已有運行配置,選擇你要修改的配置,然后點擊 Edit(編輯)。

  • 如果沒有,點擊 New Configuration(新建配置),然后選擇 Java Application 或 Spring Boot App,點擊 New(新建)。

  1. 配置 VM Arguments

  • 在 Arguments 標簽頁中,找到 VM arguments 輸入框。在這里你可以添加 JVM 啟動參數。

  • 在 VM arguments 輸入框中,添加如下參數:

    --add-opens java.base/java.lang=ALL-UNNAMED
  • 這個參數允許你訪問 Java 內部 API,解決 CGLIB 在模塊系統中的兼容性問題。

  1. 保存配置

  • 點擊 Apply(應用),然后點擊 Run(運行)以保存并應用你的配置。

運行效果

啟動 Spring Boot 項目后,訪問 http://localhost:8080,頁面上將顯示通過 CGLIB 動態代理處理后的消息,控制臺中可以看到方法執行前后的日志輸出。

總結

本文詳細介紹了如何在 Spring Boot 3.3 中使用 CGLIB 實現動態代理。通過實際的代碼示例,展示了 CGLIB 在動態代理中的應用,以及如何在 Spring Boot 項目中集成 CGLIB。我們還演示了如何通過 Thymeleaf 和 Bootstrap 實現一個簡單的前端頁面,以展示代理后的效果。希望通過這篇文章,您能對 CGLIB 動態代理有一個更深入的理解。

責任編輯:武曉燕 來源: 路條編程
相關推薦

2022-09-01 10:40:29

SpringAOPJDK

2023-12-06 08:23:44

代理模式設計模式

2024-10-17 11:24:04

2021-10-18 10:36:31

Spring Boot插件Jar

2021-10-18 12:04:22

Spring BootJava開發

2024-10-30 08:05:01

Spring參數電子簽章

2024-10-11 11:46:40

2025-02-27 00:32:35

2022-07-05 14:19:30

Spring接口CGLIB

2024-04-18 09:34:28

Reactor項目異步編程

2024-01-04 07:42:44

JavaCGLIBJDK

2024-10-15 10:38:32

2022-12-26 07:37:23

Nacos代理模式運用場景、

2024-08-09 08:46:00

Springjar 包YAML

2021-07-14 11:07:56

AOPJDKCglib

2012-09-28 10:20:14

IBMdw

2012-09-27 09:47:43

SpringJava面向對象

2017-05-11 21:30:01

Android動態代理ServiceHook

2017-04-28 08:32:40

Spring BootDubbo Activ使用

2025-04-17 03:33:00

SpringSQL動態查詢
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 麻豆天堂| 国产高清不卡 | 国产免费看| 成人精品一区二区三区中文字幕 | 久久夜色精品国产 | 亚洲福利精品 | 久久99精品久久久久久噜噜 | 成人在线看片 | 成人在线不卡 | 亚洲bt 欧美bt 日本bt | 日韩av成人在线观看 | 国产精品永久免费 | 精品在线| 亚洲欧美在线观看 | 91精品久久久久久久久久 | www.日日操 | 精品国产一区二区三区观看不卡 | 亚洲视频二区 | 超碰在线久 | 国产伦一区二区三区四区 | 成年人免费看 | 97人人澡人人爽91综合色 | 亚洲国产精品一区二区第一页 | 日韩一区二区三区在线 | 久久国产精99精产国高潮 | 亚洲一区二区av | 日韩在线欧美 | 国产目拍亚洲精品99久久精品 | 精品成人免费一区二区在线播放 | 欧美日韩三级 | 夜夜艹天天干 | 日本一区二区三区四区 | 国产精品久久久久久久久免费软件 | 亚洲人成网站777色婷婷 | 欧美中文在线 | 一级二级三级在线观看 | 欧美一级片在线观看 | 婷婷综合色 | 99成人| 国产精品视频免费看 | 日韩精品一区二区三区在线播放 |