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

Java使用動態(tài)代理和反射實現(xiàn)字段變更跟蹤的方案

 更新時間:2025年12月19日 09:12:30   作者:Full Stack Developme  
該文章介紹了如何使用Java動態(tài)代理和反射技術(shù)來跟蹤記錄對象字段的變更前和變更后的數(shù)據(jù),文章詳細(xì)講解了創(chuàng)建變更記錄數(shù)據(jù)結(jié)構(gòu)、變更跟蹤處理器、代理工廠,并通過示例展示了如何使用和運行這個代理,需要的朋友可以參考下

下面我將展示如何使用Java動態(tài)代理和反射技術(shù)來跟蹤記錄對象字段的變更前和變更后的數(shù)據(jù)。

實現(xiàn)方案

我們將創(chuàng)建一個FieldChangeTracker代理,它能夠:

  1. 在字段被修改前記錄原始值
  2. 在字段被修改后記錄新值
  3. 將所有變更記錄保存在日志中

1. 創(chuàng)建變更記錄數(shù)據(jù)結(jié)構(gòu)

import java.util.Date;

public class FieldChangeRecord {
    private String fieldName;
    private Object oldValue;
    private Object newValue;
    private Date changeTime;
    private String methodName;

    public FieldChangeRecord(String fieldName, Object oldValue, Object newValue, String methodName) {
        this.fieldName = fieldName;
        this.oldValue = oldValue;
        this.newValue = newValue;
        this.changeTime = new Date();
        this.methodName = methodName;
    }

    @Override
    public String toString() {
        return "FieldChangeRecord{" +
                "fieldName='" + fieldName + '\'' +
                ", oldValue=" + oldValue +
                ", newValue=" + newValue +
                ", changeTime=" + changeTime +
                ", methodName='" + methodName + '\'' +
                '}';
    }
}

2. 創(chuàng)建變更跟蹤處理器

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class FieldChangeTracker implements InvocationHandler {
    private final Object target;
    private final List<FieldChangeRecord> changeHistory = new ArrayList<>();

    public FieldChangeTracker(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 只攔截setter方法
        if (method.getName().startsWith("set") && args != null && args.length == 1) {
            // 獲取字段名(從setXxx轉(zhuǎn)換為xxx)
            String fieldName = method.getName().substring(3);
            fieldName = Character.toLowerCase(fieldName.charAt(0)) + fieldName.substring(1);

            try {
                // 獲取字段當(dāng)前值(變更前)
                Field field = target.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                Object oldValue = field.get(target);
                
                // 調(diào)用原始方法修改值
                Object result = method.invoke(target, args);
                
                // 獲取字段新值(變更后)
                Object newValue = field.get(target);
                
                // 記錄變更
                changeHistory.add(new FieldChangeRecord(
                    fieldName, oldValue, newValue, method.getName()));
                
                return result;
            } catch (NoSuchFieldException e) {
                // 如果沒有對應(yīng)字段,直接調(diào)用方法
                return method.invoke(target, args);
            }
        } else {
            // 非setter方法直接調(diào)用
            return method.invoke(target, args);
        }
    }

    public List<FieldChangeRecord> getChangeHistory() {
        return new ArrayList<>(changeHistory);
    }

    public void printChangeHistory() {
        System.out.println("=== Field Change History ===");
        for (FieldChangeRecord record : changeHistory) {
            System.out.println(record);
        }
        System.out.println("===========================");
    }
}

3. 創(chuàng)建代理工廠

import java.lang.reflect.Proxy;

public class TrackingProxyFactory {
    @SuppressWarnings("unchecked")
    public static <T> T createTrackingProxy(T target, Class<T> interfaceType) {
        return (T) Proxy.newProxyInstance(
                interfaceType.getClassLoader(),
                new Class<?>[]{interfaceType},
                new FieldChangeTracker(target));
    }
}

4. 示例使用

public interface User {
    String getName();
    void setName(String name);
    int getAge();
    void setAge(int age);
}

public class UserImpl implements User {
    private String name;
    private int age;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int getAge() {
        return age;
    }

    @Override
    public void setAge(int age) {
        this.age = age;
    }
}

public class Main {
    public static void main(String[] args) {
        User realUser = new UserImpl();
        User userProxy = TrackingProxyFactory.createTrackingProxy(realUser, User.class);
        
        userProxy.setName("Alice");
        userProxy.setAge(25);
        userProxy.setName("Bob");
        userProxy.setAge(30);
        
        // 獲取變更歷史
        FieldChangeTracker tracker = (FieldChangeTracker) Proxy.getInvocationHandler(userProxy);
        tracker.printChangeHistory();
    }
}

5. 示例輸出

運行上面的Main類后,輸出可能如下:

=== Field Change History ===
FieldChangeRecord{fieldName='name', oldValue=null, newValue=Alice, changeTime=..., methodName='setName'}
FieldChangeRecord{fieldName='age', oldValue=0, newValue=25, changeTime=..., methodName='setAge'}
FieldChangeRecord{fieldName='name', oldValue=Alice, newValue=Bob, changeTime=..., methodName='setName'}
FieldChangeRecord{fieldName='age', oldValue=25, newValue=30, changeTime=..., methodName='setAge'}
===========================

高級改進(jìn)

  1. 支持非接口類:可以使用CGLIB庫來代理沒有接口的類
  2. 線程安全:為changeHistory添加同步控制
  3. 過濾敏感字段:添加注解標(biāo)記不需要跟蹤的字段
  4. 持久化存儲:將變更記錄保存到數(shù)據(jù)庫或文件
  5. 性能優(yōu)化:緩存反射獲取的Field對象

CGLIB版本實現(xiàn)

如果需要代理沒有實現(xiàn)接口的類,可以使用CGLIB:

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

public class CglibTrackingProxyFactory {
    @SuppressWarnings("unchecked")
    public static <T> T createTrackingProxy(T target) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(new CglibFieldChangeTracker(target));
        return (T) enhancer.create();
    }
}

class CglibFieldChangeTracker implements MethodInterceptor {
    private final Object target;
    private final List<FieldChangeRecord> changeHistory = new ArrayList<>();

    public CglibFieldChangeTracker(Object target) {
        this.target = target;
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // 實現(xiàn)邏輯與FieldChangeTracker類似
        // ...
    }
    
    // 其他方法與FieldChangeTracker相同
}

這種實現(xiàn)方式可以跟蹤任何類的字段變更,而不僅限于實現(xiàn)了接口的類。

到此這篇關(guān)于Java使用動態(tài)代理和反射實現(xiàn)字段變更跟蹤的方案的文章就介紹到這了,更多相關(guān)Java動態(tài)代理和反射跟蹤字段變更內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一步步教你把SpringBoot項目打包成Docker鏡像

    一步步教你把SpringBoot項目打包成Docker鏡像

    Docker可以讓開發(fā)者打包他們的應(yīng)用以及依賴包到一個輕量級、可移植的容器中,然后發(fā)布到任何流行的 Linux 機(jī)器上,也可以實現(xiàn)虛擬化,下面這篇文章主要給大家介紹了關(guān)于SpringBoot項目打包成Docker鏡像的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • java實現(xiàn)字符串和數(shù)字轉(zhuǎn)換工具

    java實現(xiàn)字符串和數(shù)字轉(zhuǎn)換工具

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)字符串和數(shù)字轉(zhuǎn)換工具,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Java多線程(單例模式,阻塞隊列,定時器,線程池)詳解

    Java多線程(單例模式,阻塞隊列,定時器,線程池)詳解

    本文是多線程初級入門,主要介紹了多線程單例模式、阻塞隊列、定時器、線程池、多線程面試考點,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-09-09
  • 使用SpringBoot+EasyExcel+Vue實現(xiàn)excel表格的導(dǎo)入和導(dǎo)出詳解

    使用SpringBoot+EasyExcel+Vue實現(xiàn)excel表格的導(dǎo)入和導(dǎo)出詳解

    這篇文章主要介紹了使用SpringBoot+VUE+EasyExcel?整合導(dǎo)入導(dǎo)出數(shù)據(jù)的過程詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • spring cloud學(xué)習(xí)入門之config配置教程

    spring cloud學(xué)習(xí)入門之config配置教程

    這篇文章主要給大家介紹了關(guān)于spring cloud學(xué)習(xí)入門之config配置的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring cloud具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • Java 中的語法糖,真甜

    Java 中的語法糖,真甜

    語法糖(Syntactic sugar),也叫做糖衣語法,是英國科學(xué)家發(fā)明的一個術(shù)語,通常來說使用語法糖能夠增加程序的可讀性,從而減少程序代碼出錯的機(jī)會.這篇文章主要介紹了Java 中的語法糖知識,需要的朋友可以參考下
    2020-12-12
  • Java郵件發(fā)送超時時間過長問題的優(yōu)化方案

    Java郵件發(fā)送超時時間過長問題的優(yōu)化方案

    郵件發(fā)送是許多Java應(yīng)用中常見的功能,尤其在用戶注冊、密碼重置和系統(tǒng)通知中,對于一個高并發(fā)的系統(tǒng)來說,郵件發(fā)送的超時問題可能導(dǎo)致應(yīng)用性能的下降,甚至影響用戶體驗,因此,本期我們將討論Java郵件發(fā)送超時時間過長 的問題,并深入探討其成因和優(yōu)化策略
    2025-06-06
  • springboot的EnvironmentPostProcessor接口方法源碼解析

    springboot的EnvironmentPostProcessor接口方法源碼解析

    這篇文章主要介紹了springboot的EnvironmentPostProcessor接口方法源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • SpringBoot2.x中management.security.enabled=false無效的解決

    SpringBoot2.x中management.security.enabled=false無效的解決

    這篇文章主要介紹了SpringBoot2.x中management.security.enabled=false無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java 枚舉類定義靜態(tài)valueOf(java.lang.String)方法的問題及解決

    java 枚舉類定義靜態(tài)valueOf(java.lang.String)方法的問題及解決

    這篇文章主要介紹了java 枚舉類定義靜態(tài)valueOf(java.lang.String)方法的問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論

光山县| 分宜县| 龙州县| 洪江市| 诏安县| 那坡县| 竹山县| 通渭县| 区。| 当雄县| 图木舒克市| 宜黄县| 馆陶县| 松江区| 张掖市| 桂阳县| 监利县| 翁牛特旗| 巫溪县| 筠连县| 涿州市| 舞钢市| 皮山县| 汝州市| 马龙县| 朝阳市| 威海市| 鄂托克前旗| 开原市| 和龙市| 达拉特旗| 五常市| 莱阳市| 鲁甸县| 兴安县| 宕昌县| 攀枝花市| 科尔| 宣威市| 洞口县| 松原市|