当前位置: 首页 > news >正文

哪有做logo的网站独立网站和平台网站

哪有做logo的网站,独立网站和平台网站,营销推广策划方案范文,西安网站制作开发👆🏻👆🏻👆🏻关注博主,让你的代码变得更加优雅。 前言 Apache BeanUtils 是Java中用来复制2个对象属性的一个类型。 上一篇文章我们讲到了 Apache BeanUtils 性能相对比较差,今天…

👆🏻👆🏻👆🏻关注博主,让你的代码变得更加优雅。

前言

Apache BeanUtils 是Java中用来复制2个对象属性的一个类型。

上一篇文章我们讲到了 Apache BeanUtils 性能相对比较差,今天我不仅仅要带你学习源代码 ,更要带你手把手写一个Apache BeanUtils。

最佳实践

直接上案例

案例地址: https://github.com/zhuangjiaju/easytools/blob/main/easytools-test/src/test/java/com/github/zhuangjiaju/easytools/test/demo/beanutils/ApacheBeanUtilsTest.java

简单的复制对象

直接上代码:

创建一个java 对象:

/*** Apache BeanUtils 使用的demo*/
@Test
public void demo() throws Exception {BeanUtilsDemoDTO beanUtilsDemo = new BeanUtilsDemoDTO();beanUtilsDemo.setId("id");beanUtilsDemo.setFirstName("firstName");BeanUtilsDemoDTO newBeanUtilsDemo = new BeanUtilsDemoDTO();BeanUtils.copyProperties(newBeanUtilsDemo, beanUtilsDemo);log.info("newBeanUtilsDemo: {}", newBeanUtilsDemo);
}

输出结果:

     20:21:56.949 [main] INFO com.github.zhuangjiaju.easytools.test.demo.beanutils.ApacheBeanUtilsTest -- newBeanUtilsDemo: BeanUtilsDemoDTO(id=id, firstName=firstName, lastName=null, age=null, email=null, phoneNumber=null, address=null, city=null, state=null, country=null, major=null, gpa=null, department=null, yearOfStudy=null, advisorName=null, enrollmentStatus=null, dormitoryName=null, roommateName=null, scholarshipDetails=null, extracurricularActivities=null)

可见已经复制对象成功了,输出里面有 firstName 的值。

直接自己写一个简单的 BeanUtils

源码有点复杂,我先直接写一个简单的 BeanUtils,非常的通俗易懂,看懂了然后再看源代码就非常容易了。

复制的代码一模一样:

/*** 自己写一个简单的 BeanUtils*/
@Test
public void custom() throws Exception {BeanUtilsDemoDTO beanUtilsDemo = new BeanUtilsDemoDTO();beanUtilsDemo.setId("id");beanUtilsDemo.setFirstName("firstName");BeanUtilsDemoDTO newBeanUtilsDemo = new BeanUtilsDemoDTO();MyBeanUtils.copyProperties(newBeanUtilsDemo, beanUtilsDemo);log.info("newBeanUtilsDemo: {}", newBeanUtilsDemo);
}

我们自己实现的工具类:

前置知识:

Introspector.getBeanInfo: 是 Java 自带的一个类,可以获取一个类的 BeanInfo 信息,然后获取属性的描述资料 PropertyDescriptor
BeanInfo : bean 的描述信息
PropertyDescriptor: bean 的属性的资料信息 ,可以获取到属性的 get/set 方法
Method: 方法,用这个对象可以反射掉调用

 public static class MyBeanUtils {/*** 复制方法** @param dest* @param orig* @throws Exception*/public static void copyProperties(Object dest, Object orig) throws Exception {// 获取目标对象的 PropertyDescriptor 属性资料PropertyDescriptor[] destPropertyDescriptors = Introspector.getBeanInfo(dest.getClass(), Object.class).getPropertyDescriptors();// 获取来源对象的 PropertyDescriptor 属性资料PropertyDescriptor[] origPropertyDescriptors = Introspector.getBeanInfo(orig.getClass(), Object.class).getPropertyDescriptors();// 上面2个 在 Apache BeanUtils 还加了缓存// 循环目标对象for (PropertyDescriptor propertyDescriptor : destPropertyDescriptors) {// 获取属性名String name = propertyDescriptor.getName();// 循环来源对象的属性名for (PropertyDescriptor origPropertyDescriptor : origPropertyDescriptors) {// 2个属性名匹配上了if (name.equals(origPropertyDescriptor.getName())) {// 直接获取 method 然后反色调用即可 就设置了数据propertyDescriptor.getWriteMethod().invoke(dest,origPropertyDescriptor.getReadMethod().invoke(orig));break;}}}}
}

代码是不是非常的容易?就是循环目标对象的属性,然后循环来源对象的属性,然后匹配上了就反射调用即可。

和 Apache BeanUtils 的源码逻辑基本一样,只是没有加缓存之类的。

源码解析

org.apache.commons.beanutils.BeanUtils.copyProperties

public static void copyProperties(final Object dest, final Object orig)throws IllegalAccessException, InvocationTargetException {// BeanUtilsBean 放在了 ThreadLocal 里面,所以是不可以并发的,但是通过 ThreadLocal 保障了BeanUtilsBean不会并发 也不会每次都new // 直接调用 copyPropertiesBeanUtilsBean.getInstance().copyProperties(dest, orig);
}

org.apache.commons.beanutils.BeanUtilsBean.copyProperties

 public void copyProperties(final Object dest, final Object orig)throws IllegalAccessException, InvocationTargetException {// Validate existence of the specified beansif (dest == null) {throw new IllegalArgumentException("No destination bean specified");}if (orig == null) {throw new IllegalArgumentException("No origin bean specified");}if (log.isDebugEnabled()) {log.debug("BeanUtils.copyProperties(" + dest + ", " +orig + ")");}// Copy the properties, converting as necessaryif (orig instanceof DynaBean) {final DynaProperty[] origDescriptors =((DynaBean)orig).getDynaClass().getDynaProperties();for (DynaProperty origDescriptor : origDescriptors) {final String name = origDescriptor.getName();// Need to check isReadable() for WrapDynaBean// (see Jira issue# BEANUTILS-61)if (getPropertyUtils().isReadable(orig, name) &&getPropertyUtils().isWriteable(dest, name)) {final Object value = ((DynaBean)orig).get(name);copyProperty(dest, name, value);}}} else if (orig instanceof Map) {@SuppressWarnings("unchecked")final// Map properties are always of type <String, Object>Map<String, Object> propMap = (Map<String, Object>)orig;for (final Map.Entry<String, Object> entry : propMap.entrySet()) {final String name = entry.getKey();if (getPropertyUtils().isWriteable(dest, name)) {copyProperty(dest, name, entry.getValue());}}} else /* if (orig is a standard JavaBean) */ {// 这里比较核心 获取来源的PropertyDescriptor 属性资料 和我们自己实现的代码 一样// getPropertyDescriptors 我们会继续跟进final PropertyDescriptor[] origDescriptors =getPropertyUtils().getPropertyDescriptors(orig);// 循环来源的 属性资料for (PropertyDescriptor origDescriptor : origDescriptors) {final String name = origDescriptor.getName();if ("class".equals(name)) {continue; // No point in trying to set an object's class}if (getPropertyUtils().isReadable(orig, name) &&getPropertyUtils().isWriteable(dest, name)) {try {final Object value =getPropertyUtils().getSimpleProperty(orig, name);// 调用复制参数 // copyProperty 我们会继续跟进copyProperty(dest, name, value);} catch (final NoSuchMethodException e) {// Should not happen}}}}}

org.apache.commons.beanutils.PropertyUtilsBean.getPropertyDescriptors(java.lang.Object)
org.apache.commons.beanutils.PropertyUtilsBean.getPropertyDescriptors(java.lang.Class<?>)
org.apache.commons.beanutils.PropertyUtilsBean.getIntrospectionData

  private BeanIntrospectionData getIntrospectionData(final Class<?> beanClass) {if (beanClass == null) {throw new IllegalArgumentException("No bean class specified");}// Look up any cached information for this bean class// 和我们自己写的比,这里核心是加了一个descriptorsCache 的缓存 BeanIntrospectionData data = descriptorsCache.get(beanClass);if (data == null) {data = fetchIntrospectionData(beanClass);descriptorsCache.put(beanClass, data);}return data;
}

org.apache.commons.beanutils.PropertyUtilsBean.fetchIntrospectionData
org.apache.commons.beanutils.DefaultBeanIntrospector.introspect

 public void introspect(final IntrospectionContext icontext) {BeanInfo beanInfo = null;try {// 这里和我们自己实现的一样 可以获取一个类的 BeanInfo 信息beanInfo = Introspector.getBeanInfo(icontext.getTargetClass());} catch (final IntrospectionException e) {// no descriptors are added to the contextlog.error("Error when inspecting class " + icontext.getTargetClass(),e);return;}//  获取 bean 的 PropertyDescriptor 属性的资料信息PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();if (descriptors == null) {descriptors = new PropertyDescriptor[0];}handleIndexedPropertyDescriptors(icontext.getTargetClass(),descriptors);icontext.addPropertyDescriptors(descriptors);
}

通过以上方法,我们就拿到了 PropertyDescriptor[] origDescriptors 接下来我们看 copyProperty

org.apache.commons.beanutils.BeanUtilsBean.copyProperty

public void copyProperty(final Object bean, String name, Object value)throws IllegalAccessException, InvocationTargetException {// Trace logging (if enabled)if (log.isTraceEnabled()) {final StringBuilder sb = new StringBuilder("  copyProperty(");sb.append(bean);sb.append(", ");sb.append(name);sb.append(", ");if (value == null) {sb.append("<NULL>");} else if (value instanceof String) {sb.append((String)value);} else if (value instanceof String[]) {final String[] values = (String[])value;sb.append('[');for (int i = 0; i < values.length; i++) {if (i > 0) {sb.append(',');}sb.append(values[i]);}sb.append(']');} else {sb.append(value.toString());}sb.append(')');log.trace(sb.toString());}// Resolve any nested expression to get the actual target beanObject target = bean;final Resolver resolver = getPropertyUtils().getResolver();while (resolver.hasNested(name)) {try {target = getPropertyUtils().getProperty(target, resolver.next(name));name = resolver.remove(name);} catch (final NoSuchMethodException e) {return; // Skip this property setter}}if (log.isTraceEnabled()) {log.trace("    Target bean = " + target);log.trace("    Target name = " + name);}// Declare local variables we will requirefinal String propName = resolver.getProperty(name); // Simple name of target propertyClass<?> type = null;                         // Java type of target propertyfinal int index = resolver.getIndex(name);         // Indexed subscript value (if any)final String key = resolver.getKey(name);           // Mapped key value (if any)// Calculate the target property typeif (target instanceof DynaBean) {final DynaClass dynaClass = ((DynaBean)target).getDynaClass();final DynaProperty dynaProperty = dynaClass.getDynaProperty(propName);if (dynaProperty == null) {return; // Skip this property setter}type = dynaPropertyType(dynaProperty, value);} else {PropertyDescriptor descriptor = null;try {descriptor =getPropertyUtils().getPropertyDescriptor(target, name);if (descriptor == null) {return; // Skip this property setter}} catch (final NoSuchMethodException e) {return; // Skip this property setter}type = descriptor.getPropertyType();if (type == null) {// Most likely an indexed setter on a POJB onlyif (log.isTraceEnabled()) {log.trace("    target type for property '" +propName + "' is null, so skipping ths setter");}return;}}if (log.isTraceEnabled()) {log.trace("    target propName=" + propName + ", type=" +type + ", index=" + index + ", key=" + key);}// Convert the specified value to the required type and store itif (index >= 0) {                    // Destination must be indexedvalue = convertForCopy(value, type.getComponentType());try {getPropertyUtils().setIndexedProperty(target, propName,index, value);} catch (final NoSuchMethodException e) {throw new InvocationTargetException(e, "Cannot set " + propName);}} else if (key != null) {            // Destination must be mapped// Maps do not know what the preferred data type is,// so perform no conversions at all// FIXME - should we create or support a TypedMap?try {getPropertyUtils().setMappedProperty(target, propName,key, value);} catch (final NoSuchMethodException e) {throw new InvocationTargetException(e, "Cannot set " + propName);}} else {                             // Destination must be simplevalue = convertForCopy(value, type);try {// 核心我们看这里 设置属性值getPropertyUtils().setSimpleProperty(target, propName, value);} catch (final NoSuchMethodException e) {throw new InvocationTargetException(e, "Cannot set " + propName);}}}

org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty

public void setSimpleProperty(final Object bean,final String name, final Object value)throws IllegalAccessException, InvocationTargetException,NoSuchMethodException {if (bean == null) {throw new IllegalArgumentException("No bean specified");}if (name == null) {throw new IllegalArgumentException("No name specified for bean class '" +bean.getClass() + "'");}// Validate the syntax of the property nameif (resolver.hasNested(name)) {throw new IllegalArgumentException("Nested property names are not allowed: Property '" +name + "' on bean class '" + bean.getClass() + "'");} else if (resolver.isIndexed(name)) {throw new IllegalArgumentException("Indexed property names are not allowed: Property '" +name + "' on bean class '" + bean.getClass() + "'");} else if (resolver.isMapped(name)) {throw new IllegalArgumentException("Mapped property names are not allowed: Property '" +name + "' on bean class '" + bean.getClass() + "'");}// Handle DynaBean instances speciallyif (bean instanceof DynaBean) {final DynaProperty descriptor =((DynaBean)bean).getDynaClass().getDynaProperty(name);if (descriptor == null) {throw new NoSuchMethodException("Unknown property '" +name + "' on dynaclass '" +((DynaBean)bean).getDynaClass() + "'");}((DynaBean)bean).set(name, value);return;}// Retrieve the property setter method for the specified propertyfinal PropertyDescriptor descriptor =getPropertyDescriptor(bean, name);if (descriptor == null) {throw new NoSuchMethodException("Unknown property '" +name + "' on class '" + bean.getClass() + "'");}// 通过 PropertyDescriptor 获取道理 set 方法 的 Methodfinal Method writeMethod = getWriteMethod(bean.getClass(), descriptor);if (writeMethod == null) {throw new NoSuchMethodException("Property '" + name +"' has no setter method in class '" + bean.getClass() + "'");}// Call the property setter methodfinal Object[] values = new Object[1];values[0] = value;if (log.isTraceEnabled()) {final String valueClassName =value == null ? "<null>" : value.getClass().getName();log.trace("setSimpleProperty: Invoking method " + writeMethod+ " with value " + value + " (class " + valueClassName + ")");}// 这个方法就是 简单的 writeMethod 调用 invoke 方法 这样子我们的值就设置好了invokeMethod(writeMethod, bean, values);

好了,这样子一个值就复制到新的对象里面了,是不是很简单?

总结

今天学习了 Apache BeanUtils 的源码,总体上就是一个缓存+反射的调用,看是记不住的,大家赶快打开自己的电脑跟几遍源码吧。

后面还会带大家看 Spring BeanUtils 的源码,欢迎持续关注。

写在最后

给大家推荐一个非常完整的Java项目搭建的最佳实践,也是本文的源码出处,由大厂程序员&EasyExcel作者维护,地址:https://github.com/zhuangjiaju/easytools


文章转载自:
http://cirl.jqLx.cn
http://unsayable.jqLx.cn
http://cobber.jqLx.cn
http://espionage.jqLx.cn
http://aqueduct.jqLx.cn
http://olefin.jqLx.cn
http://microanalyser.jqLx.cn
http://kruller.jqLx.cn
http://nodulation.jqLx.cn
http://myelocyte.jqLx.cn
http://klunk.jqLx.cn
http://thermotolerant.jqLx.cn
http://corporation.jqLx.cn
http://puddler.jqLx.cn
http://rigorist.jqLx.cn
http://quinquenniad.jqLx.cn
http://paludose.jqLx.cn
http://treeless.jqLx.cn
http://determinantal.jqLx.cn
http://pantsuit.jqLx.cn
http://repeater.jqLx.cn
http://maxim.jqLx.cn
http://anemography.jqLx.cn
http://werwolf.jqLx.cn
http://adrenergic.jqLx.cn
http://frenzied.jqLx.cn
http://lez.jqLx.cn
http://indistinctive.jqLx.cn
http://indiscreetly.jqLx.cn
http://anvers.jqLx.cn
http://candent.jqLx.cn
http://garefowl.jqLx.cn
http://snapback.jqLx.cn
http://monogram.jqLx.cn
http://facetiosity.jqLx.cn
http://truckway.jqLx.cn
http://altorilievo.jqLx.cn
http://edemata.jqLx.cn
http://hygrology.jqLx.cn
http://polyvinylidene.jqLx.cn
http://glue.jqLx.cn
http://epicist.jqLx.cn
http://yttric.jqLx.cn
http://switch.jqLx.cn
http://caseharden.jqLx.cn
http://cothurnus.jqLx.cn
http://refight.jqLx.cn
http://bootlicker.jqLx.cn
http://midday.jqLx.cn
http://isospore.jqLx.cn
http://lopsided.jqLx.cn
http://unrestrained.jqLx.cn
http://subvene.jqLx.cn
http://wuzzy.jqLx.cn
http://monoacidic.jqLx.cn
http://saltillo.jqLx.cn
http://massicot.jqLx.cn
http://innuit.jqLx.cn
http://prohibitor.jqLx.cn
http://qiviut.jqLx.cn
http://goody.jqLx.cn
http://spoof.jqLx.cn
http://perceivably.jqLx.cn
http://bauson.jqLx.cn
http://diazotization.jqLx.cn
http://aforehand.jqLx.cn
http://carnalism.jqLx.cn
http://mutability.jqLx.cn
http://leonora.jqLx.cn
http://caparison.jqLx.cn
http://pyorrhea.jqLx.cn
http://deficiently.jqLx.cn
http://unpeace.jqLx.cn
http://jerboa.jqLx.cn
http://ghostwrite.jqLx.cn
http://appraisable.jqLx.cn
http://bunker.jqLx.cn
http://hydrosphere.jqLx.cn
http://cnaa.jqLx.cn
http://liar.jqLx.cn
http://indulgency.jqLx.cn
http://twiggery.jqLx.cn
http://subscription.jqLx.cn
http://psychosis.jqLx.cn
http://genetic.jqLx.cn
http://coco.jqLx.cn
http://dicentra.jqLx.cn
http://heteroduplex.jqLx.cn
http://mercia.jqLx.cn
http://phenix.jqLx.cn
http://ictal.jqLx.cn
http://strake.jqLx.cn
http://joltily.jqLx.cn
http://jayvee.jqLx.cn
http://irani.jqLx.cn
http://counterboy.jqLx.cn
http://opprobrium.jqLx.cn
http://agriculturalist.jqLx.cn
http://sclerosis.jqLx.cn
http://homicidal.jqLx.cn
http://www.hrbkazy.com/news/62861.html

相关文章:

  • asp.net 网站修改发布识图找图
  • 厦门做网站优化的公司seo网络公司
  • wordpress目录分站长沙seo智优营家
  • 网站编辑楼盘详情页怎么做百度登录首页
  • app网站开发招聘接外包项目的网站
  • b站24小时直播间十大软件百度下载安装到桌面上
  • 深圳公司注册地址有什么要求网站seo搜索
  • vue做pc网站公众号推广一个6元
  • 网站地图在首页做链接好用的种子搜索引擎
  • 网站建设吴中区百度推广后台登陆
  • 私做政府网站小红书seo是什么
  • 做网站考虑的方面b站在哪付费推广
  • 宁波网站推广营销公司视频seo优化教程
  • 没有建网站怎样做网销成都网站推广
  • 做写字楼租赁用什么网站好福州百度快速优化
  • wordpress站添加根部单页打不开市场推广专员
  • 创意网站模板下载自己手机怎么免费做网站
  • 湄潭建设局官方网站alexa排名查询统计
  • 湖南湘江新区最新消息网站seo综合诊断
  • 网站建设 甘肃长沙网站seo收费
  • win10搭建wordpress站长工具seo推广 站长工具查询
  • wordpress安装ssl公司网站seo公司
  • 孝感网站开发培训机构如何让自己的网站快速被百度收录
  • 重庆网站建设制作设计公司永久不收费的软件app
  • 无锡高端网站建设开发优化方案英语
  • 容桂网站制作公司成都网络营销公司
  • 新疆建设厅统计报表网站交换友情链接平台
  • 龙岗商城网站建设最好网站优化方法
  • 怎么样在公司配置服务器做网站网上接单平台
  • 沾益住房和城乡建设局网站产品线上营销方案