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

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à)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

1.應(yīng)用場景

之前對(duì)接三方平臺(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)對(duì)象
 */
 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);
 }
 /**
 * 獲取對(duì)象
 *
 * @return
 */
 public Object getTarget() {
  return this.target;
 }
 /**
 * 根據(jù)屬性生成對(duì)象
 *
 * @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)文章

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

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

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

    EJB輕松進(jìn)階之一

    EJB輕松進(jìn)階之一...
    2006-12-12
  • Java中join線程操作實(shí)例分析

    Java中join線程操作實(shí)例分析

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評(píng)論

赞皇县| 屏东县| 呼伦贝尔市| 吴川市| 中牟县| 泰宁县| 曲靖市| 自贡市| 福贡县| 中卫市| 长丰县| 明水县| 徐汇区| 射洪县| 鄂托克前旗| 湘潭市| 泾源县| 芜湖县| 北海市| 紫金县| 清徐县| 柘城县| 西盟| 昌邑市| 香港 | 阿拉善左旗| 岗巴县| 高碑店市| 阜宁县| 崇文区| 泽普县| 平南县| 阳信县| 东明县| 和政县| 新竹市| 永春县| 县级市| 张家川| 娄底市| 汝城县|