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

Java cglib為實體類(javabean)動態(tài)添加屬性方式

 更新時間:2021年02月19日 09:37:38   作者:writeanewworld  
這篇文章主要介紹了Java cglib為實體類(javabean)動態(tài)添加屬性方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

1.應(yīng)用場景

之前對接三方平臺遇到一個參數(shù)名稱是變化的,然后我就想到了動態(tài)javabean怎么生成,其實是我想多了,用個map就輕易解決了,但還是記錄下動態(tài)屬性添加的實現(xiàn)吧。

2.引入依賴

 <!--使用cglib 為javabean動態(tài)添加屬性-->
 <dependency>
  <groupId>commons-beanutils</groupId>
  <artifactId>commons-beanutils</artifactId>
  <version>1.9.3</version>
 </dependency>
 <dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib-nodep</artifactId>
  <version>3.2.4</version>
 </dependency>

3.代碼如下

 import com.freemud.waimai.menu.dpzhcto.dto.DynamicBean;
 import com.google.common.collect.Maps;
 import org.apache.commons.beanutils.PropertyUtilsBean;
 import java.beans.PropertyDescriptor;
 import java.util.Map;
  public class PicBeanAddPropertiesUtil {
  public static Object getTarget(Object dest, Map<String, Object> addProperties) {
  // get property map
  PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
  PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(dest);
  Map<String, Class> propertyMap = Maps.newHashMap();
  for (PropertyDescriptor d : descriptors) {
   if (!"class".equalsIgnoreCase(d.getName())) {
    propertyMap.put(d.getName(), d.getPropertyType());
   }
  }
  // add extra properties
  addProperties.forEach((k, v) -> propertyMap.put(k, v.getClass()));
  // new dynamic bean
   DynamicBean dynamicBean = new DynamicBean(dest.getClass(), propertyMap);
  // add old value
  propertyMap.forEach((k, v) -> {
   try {
    // filter extra properties
    if (!addProperties.containsKey(k)) {
     dynamicBean.setValue(k, propertyUtilsBean.getNestedProperty(dest, k));
    }
   } catch (Exception e) {
    e.printStackTrace();
   }
  });
  // add extra value
  addProperties.forEach((k, v) -> {
   try {
    dynamicBean.setValue(k, v);
   } catch (Exception e) {
    e.printStackTrace();
   }
  });
  Object target = dynamicBean.getTarget();
  return target;
  }
  }
import net.sf.cglib.beans.BeanGenerator;
import net.sf.cglib.beans.BeanMap;
import java.util.Map;
public class DynamicBean {
 /**
 * 目標對象
 */
 private Object target;
 /**
 * 屬性集合
 */
 private BeanMap beanMap;
 public DynamicBean(Class superclass, Map<String, Class> propertyMap) {
  this.target = generateBean(superclass, propertyMap);
  this.beanMap = BeanMap.create(this.target);
 }
 /**
 * bean 添加屬性和值
 *
 * @param property
 * @param value
 */
 public void setValue(String property, Object value) {
  beanMap.put(property, value);
 }
 /**
 * 獲取屬性值
 *
 * @param property
 * @return
 */
 public Object getValue(String property) {
  return beanMap.get(property);
 }
 /**
 * 獲取對象
 *
 * @return
 */
 public Object getTarget() {
  return this.target;
 }
 /**
 * 根據(jù)屬性生成對象
 *
 * @param superclass
 * @param propertyMap
 * @return
 */
 private Object generateBean(Class superclass, Map<String, Class> propertyMap) {
  BeanGenerator generator = new BeanGenerator();
  if (null != superclass) {
   generator.setSuperclass(superclass);
  }
  BeanGenerator.addProperties(generator, propertyMap);
  return generator.create();
 }
}
public static void main(String[] args) {
  FinalPicBaseReqDto entity = new FinalPicBaseReqDto();
  entity.setAppKey("eee");
  entity.setContent("222");
  Map<String, Object> addProperties = new HashMap() {{
   put("動態(tài)屬性名", "動態(tài)屬性值");
  }};
  FinalPicBaseReqDto finalPicBaseReqVo = (FinalPicBaseReqDto) PicBeanAddPropertiesUtil.getTarget(entity, addProperties);
  System.out.println(JSON.toJSONString(finalPicBaseReqVo));
 }

可以看到實體類只有兩個屬性,但是最終是動態(tài)添加進去了新的屬性。

聲明:代碼也是前人造的輪子,歡迎各位拿去使用,解決實際生產(chǎn)中遇到的相似場景問題

補充:JavaBean動態(tài)添加刪除屬性

1.cglib

BeanGenerator beanGenerator = new BeanGenerator();
beanGenerator.addProperty("id", Long.class);
beanGenerator.addProperty("username", String.class);
Object obj = beanGenerator.create();
BeanMap beanMap = BeanMap.create(obj);
BeanCopier copier = BeanCopier.create(User.class, obj.getClass(), false);
User user = new User();
user.setId(1L);
user.setUsername("name1");
user.setPassword("123");
copier.copy(user, obj, null);
System.out.println(beanMap.get("username"));Class clazz = obj.getClass();
Method[] methods = clazz.getDeclaredMethods();for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i].getName());
}

輸出結(jié)果:

name1
getId
getUsername
setId
setUsername

從輸出結(jié)果可以看出最后生成的obj只有id和username兩個屬性

2.org.apache.commons.beanutils

DynaProperty property = new DynaProperty("id", Long.class);
DynaProperty property1 = new DynaProperty("username", String.class);
BasicDynaClass basicDynaClass = new BasicDynaClass("user", null, newDynaProperty[]{property, property1});
BasicDynaBean basicDynaBean = new BasicDynaBean(basicDynaClass);
User user = new User();
user.setId(1L);
user.setUsername("name1");
user.setPassword("123");
BeanUtils.copyProperties(basicDynaBean, user);Map<String, Object> map = basicDynaBean.getMap();
Iterator<String> it = map.keySet().iterator();while (it.hasNext()) { String key = it.next();
System.out.println(key + ":" + map.get(key));
}

輸入結(jié)果:

id:1username:name1

查看BasicDynaBean與BasicDynaClass之間的關(guān)系

DynaBean的源碼

public interface DynaBean {
public boolean contains(String name, String key);
public Object get(String name);
public Object get(String name, int index);
public Object get(String name, String key);
public DynaClass getDynaClass();
public void remove(String name, String key);
public void set(String name, Object value);
public void set(String name, int index, Object value);
public void set(String name, String key, Object value);
}

主要是接口的定義

再來看看BasicDynaBean是怎么實現(xiàn)的,直接看public Object get(String name);

/**
* Return the value of a simple property with the specified name.
*
* @param name Name of the property whose value is to be retrieved
* @return The property's value
*
* @exception IllegalArgumentException if there is no property
* of the specified name
*/public Object get(String name) { // Return any non-null value for the specified property
Object value = values.get(name); if (value != null) { return (value);
} // Return a null value for a non-primitive property
Class<?> type = getDynaProperty(name).getType(); if (!type.isPrimitive()) { return(value);
} // Manufacture default values for primitive properties
if (type == Boolean.TYPE) { return (Boolean.FALSE);
} else if (type == Byte.TYPE) { return (new Byte((byte) 0));
} else if (type == Character.TYPE) { return (new Character((char) 0));
} else if (type == Double.TYPE) { return (new Double(0.0));
} else if (type == Float.TYPE) { return (new Float((float) 0.0));
} else if (type == Integer.TYPE) { return (new Integer(0));
} else if (type == Long.TYPE) { return (new Long(0));
} else if (type == Short.TYPE) { return (new Short((short) 0));
} else { return (null);
}
}

從以上代碼可以看出是在values里取值的

/**
* The set of property values for this DynaBean, keyed by property name.
*/
protected HashMap<String, Object> values = new HashMap<String, Object>();

其實是用HashMap來實現(xiàn)的.

3.總結(jié)

用cglib動態(tài)刪除添加屬性時,雖然obj里有g(shù)etUsername這個方法,卻不能obj.getUsername()這樣直接調(diào)用,想得到username的值只能通過beanMap.get("username")獲取.

org.apache.commons.beanutils從源碼來看是使用HashMap來實現(xiàn)的.

兩種方式從操作角度來說和使用Map的區(qū)別不大.只是它們都提供了復(fù)制屬性的工具方法.

相關(guān)文章

  • StringUtils中的isEmpty、isNotEmpty、isBlank和isNotBlank的區(qū)別詳解

    StringUtils中的isEmpty、isNotEmpty、isBlank和isNotBlank的區(qū)別詳解

    這篇文章主要介紹了StringUtils中的isEmpty、isNotEmpty、isBlank和isNotBlank的區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • EJB輕松進階之一

    EJB輕松進階之一

    EJB輕松進階之一...
    2006-12-12
  • Java中join線程操作實例分析

    Java中join線程操作實例分析

    這篇文章主要介紹了Java中join線程操作,結(jié)合實例形式分析了java使用join方法操作線程的相關(guān)原理與實現(xiàn)技巧,需要的朋友可以參考下
    2019-09-09
  • 基于Java實現(xiàn)考試管理系統(tǒng)

    基于Java實現(xiàn)考試管理系統(tǒng)

    這篇文章主要介紹了基于Java實現(xiàn)的考試管理系統(tǒng),項目運用到的技術(shù)有Springboot、Maven、Jpa、Vue等等,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2021-12-12
  • Spring中基于xml的AOP實現(xiàn)詳解

    Spring中基于xml的AOP實現(xiàn)詳解

    這篇文章主要介紹了Spring中基于xml的AOP實現(xiàn)詳解,基于xml與基于注解的AOP本質(zhì)上是非常相似的,都是需要封裝橫切關(guān)注點,封裝到切面中,然后把橫切關(guān)注點封裝為一個方法,再把該方法設(shè)置為當(dāng)前的一個通知,再通過切入點表達式定位到橫切點就可以了,需要的朋友可以參考下
    2023-09-09
  • 關(guān)于Java8新特性O(shè)ptional類的詳細解讀

    關(guān)于Java8新特性O(shè)ptional類的詳細解讀

    Optional類是一個容器類,它可以保存類型T的值,代表這個值存在?;蛘邇H僅保存null,表示這個值不存在,原來用 null 表示一個值不存在,現(xiàn)在Optional 可以更好的表達這個概念。并且可以避免空指針異常,需要的朋友可以參考下
    2023-05-05
  • java中 == 與 equal 的區(qū)別講解

    java中 == 與 equal 的區(qū)別講解

    這篇文章介紹了java中 == 與 equal 的區(qū)別,有需要的朋友可以參考一下
    2013-10-10
  • Java實現(xiàn)Http工具類的封裝操作示例

    Java實現(xiàn)Http工具類的封裝操作示例

    這篇文章主要介紹了Java實現(xiàn)Http工具類的封裝操作,涉及java針對http請求與響應(yīng)、遠程交互與字符串拼接等操作封裝技巧,需要的朋友可以參考下
    2018-01-01
  • 解決Springboot獲取不到nacos配置中心的配置問題

    解決Springboot獲取不到nacos配置中心的配置問題

    由于項目使用的nacos老版本,存在風(fēng)險bug, 需要將nacos升級至2.2.1及以上版本,版本升級完畢之后 啟動項目發(fā)現(xiàn)項目開始報錯,所以本文記錄一下Springboot獲取不到nacos配置中心的配置問題,文中有詳細的解決方法,需要的朋友可以參考下
    2023-09-09
  • springboot冪等切片的實現(xiàn)

    springboot冪等切片的實現(xiàn)

    本文主要介紹了springboot冪等切片的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評論

江阴市| 如皋市| 赤峰市| 天峻县| 陆川县| 体育| 九江县| 桃园县| 宜城市| 普兰县| 呼玛县| 巴彦县| 当阳市| 大姚县| 刚察县| 星座| 剑河县| 左贡县| 哈尔滨市| 龙井市| 邵东县| 黄冈市| 潢川县| 偃师市| 西平县| 凤阳县| 望奎县| 金堂县| 任丘市| 花莲县| 泾川县| 巫溪县| 邓州市| 张家港市| 宣威市| 九江市| 万山特区| 江口县| 聊城市| 太仆寺旗| 石嘴山市|