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

java反射機制及beanUtils的實現(xiàn)原理分析

 更新時間:2024年12月10日 14:53:07   作者:linab112  
本文介紹了Java的反射機制、VO、DTO、PO的概念以及BeanUtils的實現(xiàn)原理和簡單示例,通過反射可以在運行時動態(tài)操作類、方法和字段,BeanUtils用于在不同bean之間進行屬性復(fù)制

1.反射機制說明

Java的反射機制允許程序在運行時檢查和操作類、方法、字段等結(jié)構(gòu)。通過反射,可以動態(tài)地創(chuàng)建對象、調(diào)用方法、獲取/設(shè)置字段的值,而無需在編譯時確定這些操作。

反射的核心類是java.lang.reflect包中的Method、FieldConstructor等。使用反射需要注意性能開銷和安全性問題。

  • 獲取類的Class對象
Class<?> clazz = MyClass.class;
  • 實例化對象
MyClass myObject = (MyClass) clazz.getDeclaredConstructor().newInstance();
  • 獲取和調(diào)用方法
Method method = clazz.getDeclaredMethod("methodName", parameterTypes);
method.setAccessible(true); // 如果方法是private的,需要設(shè)置accessible為true
Object result = method.invoke(myObject, args);
  • 獲取和設(shè)置字段值
Field field = clazz.getDeclaredField("fieldName");
field.setAccessible(true); // 如果字段是private的,需要設(shè)置accessible為true
Object value = field.get(myObject);
field.set(myObject, newValue);
  • 操作構(gòu)造函數(shù)
Constructor<?> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true); // 如果構(gòu)造函數(shù)是private的,需要設(shè)置accessible為true
MyClass myObject = (MyClass) constructor.newInstance(args);

2.VO,DTO,PO的說明

VO(Value Object)值對象

VO就是展示用的數(shù)據(jù),不管展示方式是網(wǎng)頁,還是客戶端,還是APP,只要是這個東西是讓人看到的,這就叫VO,這個大家都很理解,反正就是我們的接口返回給前端的對象都是用VO來返回,跟DTO不一樣的是,VO是我們返回給前端,DTO是我們從前端接收的時候用的,即一個是入?yún)?,一個是返回結(jié)果

DTO(Data Transfer Object)數(shù)據(jù)傳輸對象

這個傳輸通常指的前后端之間的傳輸

DTO是一個比較特殊的對象,他有兩種存在形式:

  • 一種是前端和后端交互所使用的對象
  • 另一種是微服務(wù)之間的一種傳輸對象,我們一般也是用DTO來進行傳輸

PO(Persistant Object)持久對象

PO比較好理解,簡單說PO就是數(shù)據(jù)庫中的記錄,一個PO的數(shù)據(jù)結(jié)構(gòu)對應(yīng)著庫中表的結(jié)構(gòu),表中的一條記錄就是一個PO對象,通常PO里面除了get,set之外沒有別的方法,對于PO來說,數(shù)量是相對固定的,一定不會超過數(shù)據(jù)庫表的數(shù)量,等同于BO,這倆概念是一致的

3.beanUtils的實現(xiàn)原理

在后端的各個層中進行數(shù)據(jù)傳輸時,經(jīng)常使用beanUtils進行bean的拷貝,其實現(xiàn)原理就是通過java的放射機制實現(xiàn)。

package org.springframework.beans;

    private static void copyProperties(Object source, Object target, @Nullable Class<?> editable, @Nullable String... ignoreProperties) throws BeansException {
        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");
        Class<?> actualEditable = target.getClass();
        if (editable != null) {
            if (!editable.isInstance(target)) {
                throw new IllegalArgumentException("Target class [" + target.getClass().getName() + "] not assignable to Editable class [" + editable.getName() + "]");
            }

            actualEditable = editable;
        }

        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
        List<String> ignoreList = ignoreProperties != null ? Arrays.asList(ignoreProperties) : null;
        PropertyDescriptor[] var7 = targetPds;
        int var8 = targetPds.length;

        for(int var9 = 0; var9 < var8; ++var9) {
            PropertyDescriptor targetPd = var7[var9];
            Method writeMethod = targetPd.getWriteMethod();
            if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
                if (sourcePd != null) {
                    Method readMethod = sourcePd.getReadMethod();
                    if (readMethod != null) {
                        ResolvableType sourceResolvableType = ResolvableType.forMethodReturnType(readMethod);
                        ResolvableType targetResolvableType = ResolvableType.forMethodParameter(writeMethod, 0);
                        boolean isAssignable = !sourceResolvableType.hasUnresolvableGenerics() && !targetResolvableType.hasUnresolvableGenerics() ? targetResolvableType.isAssignableFrom(sourceResolvableType) : ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType());
                        if (isAssignable) {
                            try {
                                if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                                    readMethod.setAccessible(true);
                                }

                                Object value = readMethod.invoke(source);
                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                    writeMethod.setAccessible(true);
                                }

                                writeMethod.invoke(target, value);
                            } catch (Throwable var18) {
                                throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", var18);
                            }
                        }
                    }
                }
            }
        }

    }

4.beanUtils的簡單示例

public class BeanToolUtils {

    public static void copy(Object source, Object target) throws Exception {
        Class<?> sourceClass = source.getClass();
        Class<?> targeteClass = target.getClass();
        Field[] fields = targeteClass.getDeclaredFields();
        // 輸出字段信息
        for (Field field : fields) {
            String name = field.getName();
            if ("serialVersionUID".equals(name)) {
                continue;
            }
            String getterName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
            String setterName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);

            Method getMethod = sourceClass.getMethod(getterName);
            if(!ObjectUtils.isEmpty(getMethod)){
                Object val = getMethod.invoke(source);

                Method setMethod = targeteClass.getMethod(setterName,field.getType());
                setMethod.invoke(target, val);
            }

        }
    }
}

說明:

獲取目標bean的class對象,通過class對象獲取目標bean的所有屬性,循環(huán)屬性信息,獲取屬性的get和set方法,執(zhí)行來源bean的get方法獲取屬性值,執(zhí)行目標bean的set方法,設(shè)置屬性值,完成bean的賦值操作。

總結(jié)

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

相關(guān)文章

  • SpringBoot3.X 整合 MinIO 存儲原生方案

    SpringBoot3.X 整合 MinIO 存儲原生方案

    本文詳細介紹了SpringBoot3.X整合MinIO的原生方案,從環(huán)境搭建到核心功能實現(xiàn),涵蓋了文件上傳、下載、刪除等常用操作,并補充了異常處理、參數(shù)校驗、安全實踐等內(nèi)容,感興趣的朋友一起看看吧
    2025-07-07
  • Liquibase結(jié)合SpringBoot使用實現(xiàn)數(shù)據(jù)庫管理功能

    Liquibase結(jié)合SpringBoot使用實現(xiàn)數(shù)據(jù)庫管理功能

    Liquibase 是一個強大的數(shù)據(jù)庫管理工具,它幫助你通過自動化管理數(shù)據(jù)庫的變更、版本控制、和回滾,簡化了開發(fā)中的數(shù)據(jù)庫遷移工作,這篇文章主要介紹了Liquibase結(jié)合SpringBoot使用實現(xiàn)數(shù)據(jù)庫管理,需要的朋友可以參考下
    2024-12-12
  • SpringBoot2.動態(tài)@Value的實現(xiàn)方式

    SpringBoot2.動態(tài)@Value的實現(xiàn)方式

    這篇文章主要介紹了SpringBoot2.動態(tài)@Value的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • spring中12種@Transactional的失效場景(小結(jié))

    spring中12種@Transactional的失效場景(小結(jié))

    日常我們進行業(yè)務(wù)開發(fā)時,基本上使用的都是聲明式事務(wù),即為使用@Transactional注解的方式,本文主要介紹了spring中12種@Transactional的失效場景,感興趣的小伙伴們可以參考一下
    2022-01-01
  • JAVA 對50取余數(shù)的五種方法試下

    JAVA 對50取余數(shù)的五種方法試下

    在數(shù)學(xué)計算中經(jīng)常會遇到余數(shù),本文主要介紹了JAVA 對50取余數(shù)的五種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • Java中求最大值的4種方法實例代碼

    Java中求最大值的4種方法實例代碼

    這篇文章主要給大家介紹了關(guān)于Java中求最大值的4種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 基于Java編寫一個數(shù)據(jù)庫比較工具類

    基于Java編寫一個數(shù)據(jù)庫比較工具類

    這篇文章主要為大家詳細介紹了如何基于Java編寫一個數(shù)據(jù)庫比較工具類,其中比較結(jié)果會以現(xiàn)數(shù)據(jù)庫的視角說明,感興趣的小伙伴可以了解一下
    2023-07-07
  • 深入理解java中的synchronized關(guān)鍵字

    深入理解java中的synchronized關(guān)鍵字

    這篇文章主要介紹了java中的synchronized關(guān)鍵字,有需要的朋友可以參考一下
    2013-12-12
  • SpringBoot?+?Disruptor實現(xiàn)特快高并發(fā)處理及使用Disruptor高速實現(xiàn)隊列的過程

    SpringBoot?+?Disruptor實現(xiàn)特快高并發(fā)處理及使用Disruptor高速實現(xiàn)隊列的過程

    Disruptor是一個開源的Java框架,它被設(shè)計用于在生產(chǎn)者—消費者(producer-consumer problem,簡稱PCP)問題上獲得盡量高的吞吐量(TPS)和盡量低的延遲,這篇文章主要介紹了SpringBoot?+?Disruptor?實現(xiàn)特快高并發(fā)處理,使用Disruptor高速實現(xiàn)隊列,需要的朋友可以參考下
    2023-11-11
  • SpringBoot快速整合通用Mapper的示例代碼

    SpringBoot快速整合通用Mapper的示例代碼

    后端業(yè)務(wù)開發(fā),每個表都要用到單表的?增刪改查?等通用方法,而配置了通用Mapper可以極大的方便使用Mybatis單表的增刪改查操作,這篇文章主要介紹了SpringBoot快速整合通用Mapper,需要的朋友可以參考下
    2022-07-07

最新評論

徐水县| 乌拉特中旗| 监利县| 林州市| 淮阳县| 博客| 临沂市| 永寿县| 房山区| 宜兰县| 龙岩市| 呼伦贝尔市| 宁晋县| 那曲县| 独山县| 固镇县| 四子王旗| 获嘉县| 河东区| 从江县| 乌恰县| 阳春市| 仲巴县| 凌源市| 镇安县| 南靖县| 梓潼县| 沂水县| 安丘市| 襄城县| 孟州市| 星子县| 靖远县| 韶山市| 潍坊市| 抚松县| 阳原县| 定西市| 宁安市| 福建省| 丰顺县|