欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

1.應(yīng)用場景

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

2.引入依賴

 <!--使用cglib 為javabean動(dòng)態(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 {
 /**
 * 目標(biāo)對象
 */
 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("動(dòng)態(tài)屬性名", "動(dòng)態(tài)屬性值");
  }};
  FinalPicBaseReqDto finalPicBaseReqVo = (FinalPicBaseReqDto) PicBeanAddPropertiesUtil.getTarget(entity, addProperties);
  System.out.println(JSON.toJSONString(finalPicBaseReqVo));
 }

可以看到實(shí)體類只有兩個(gè)屬性,但是最終是動(dòng)態(tài)添加進(jìn)去了新的屬性。

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

補(bǔ)充:JavaBean動(dòng)態(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兩個(gè)屬性

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是怎么實(shí)現(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>();

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

3.總結(jié)

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

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

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

相關(guān)文章

  • Java對象級別與類級別的同步鎖synchronized語法示例

    Java對象級別與類級別的同步鎖synchronized語法示例

    這篇文章主要為大家介紹了Java對象級別與類級別的同步鎖synchronized語法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • idea 離線安裝lombok插件的方法步驟(圖文)

    idea 離線安裝lombok插件的方法步驟(圖文)

    這篇文章主要介紹了idea 離線安裝lombok插件的方法步驟(圖文),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • Java?新特性之Option示例詳解

    Java?新特性之Option示例詳解

    使用Optional開發(fā)時(shí)要注意正確使用Optional的“姿勢”,特別注意不要使用3.2節(jié)提到的錯(cuò)誤示范,謹(jǐn)慎使用isPresent()和get()方法,盡量多使用map()、filter()、orElse()等方法來發(fā)揮Optional的作用,對Java??Option相關(guān)知識感興趣的朋友一起看看吧
    2024-02-02
  • Java集合之CopyOnWriteArrayList詳解

    Java集合之CopyOnWriteArrayList詳解

    這篇文章主要介紹了Java集合之CopyOnWriteArrayList詳解,CopyOnWriteArrayList是ArrayList的線程安全版本,內(nèi)部也是通過數(shù)組實(shí)現(xiàn),每次對數(shù)組的修改都完全拷貝一份新的數(shù)組來修改,修改完了再替換掉老數(shù)組,這樣保證了只阻塞寫操作,需要的朋友可以參考下
    2023-12-12
  • Spring Boot 2.4版本前后的分組配置變化及對多環(huán)境配置結(jié)構(gòu)的影響(推薦)

    Spring Boot 2.4版本前后的分組配置變化及對多環(huán)境配置結(jié)構(gòu)的影響(推薦)

    這篇文章主要介紹了Spring Boot 2.4版本前后的分組配置變化及對多環(huán)境配置結(jié)構(gòu)的影響,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Spring?Cloud?OpenFeign?遠(yuǎn)程調(diào)用

    Spring?Cloud?OpenFeign?遠(yuǎn)程調(diào)用

    這篇文章主要介紹了Spring?Cloud?OpenFeign?遠(yuǎn)程調(diào)用,本文通過遠(yuǎn)程調(diào)用的GitHub開放API用到的OpenFeign作為示例代碼作為入口進(jìn)行講解。然后以圖解+解讀源碼的方式深入剖析了OpenFeign的運(yùn)行機(jī)制和架構(gòu)設(shè)計(jì),需要的朋友可以參考一下
    2022-08-08
  • java 圖片加水印實(shí)例代碼

    java 圖片加水印實(shí)例代碼

    java 圖片加水印實(shí)例代碼,需要的朋友可以參考一下
    2013-06-06
  • 新建Maven工程出現(xiàn)Process?Terminated的問題解決

    新建Maven工程出現(xiàn)Process?Terminated的問題解決

    當(dāng)Maven出現(xiàn)"Process terminated"錯(cuò)誤時(shí),這通常是由于配置文件或路徑錯(cuò)誤導(dǎo)致的,本文主要介紹了新建Maven工程出現(xiàn)Process?Terminated的問題解決,感興趣的可以了解一下
    2024-04-04
  • Redis 訂閱發(fā)布_Jedis實(shí)現(xiàn)方法

    Redis 訂閱發(fā)布_Jedis實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄猂edis 訂閱發(fā)布_Jedis實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Java WebService 簡單實(shí)例(附實(shí)例代碼)

    Java WebService 簡單實(shí)例(附實(shí)例代碼)

    本篇文章主要介紹了Java WebService 簡單實(shí)例(附實(shí)例代碼), Web Service 是一種新的web應(yīng)用程序分支,他們是自包含、自描述、模塊化的應(yīng)用,可以發(fā)布、定位、通過web調(diào)用。有興趣的可以了解一下
    2017-01-01

最新評論