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

网站制作公司北京网站建设公司站内seo优化

网站制作公司北京网站建设公司,站内seo优化,网站砍价活动怎么做,网站的关键词和描述#x1f446;#x1f3fb;#x1f446;#x1f3fb;#x1f446;#x1f3fb;关注博主#xff0c;让你的代码变得更加优雅。 前言 Apache BeanUtils 是Java中用来复制2个对象属性的一个类型。 上一篇文章我们讲到了 Apache BeanUtils 性能相对比较差#xff0c;今天…关注博主让你的代码变得更加优雅。 前言 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(idid, firstNamefirstName, lastNamenull, agenull, emailnull, phoneNumbernull, addressnull, citynull, statenull, countrynull, majornull, gpanull, departmentnull, yearOfStudynull, advisorNamenull, enrollmentStatusnull, dormitoryNamenull, roommateNamenull, scholarshipDetailsnull, extracurricularActivitiesnull)可见已经复制对象成功了输出里面有 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, ObjectMapString, Object propMap (MapString, Object)orig;for (final Map.EntryString, 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 objects 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://www.w-s-a.com/news/108917/

相关文章:

  • 柳州购物网站开发设计服装网站的建设与管理
  • 做网站的上海市哪家技术好北京百姓网免费发布信息
  • 网站文章排版制作网站软件
  • 云南网站开发公司网站商城定制网站建设
  • 企业网站的新闻资讯版块有哪些肇庆自助建站模板
  • 怎么做平台网站吗为网站做seo需要什么
  • 苏州吴江建设局招标网站海南网站搭建价格
  • 网站建设主要研究内容用哪个程序做网站收录好
  • 网站建设如何开单装修设计图免费
  • 做内容网站赚钱吗seo推广具体做什么
  • 连山区网站建设seo简历
  • 自助建站系统官方版太仓高端网站制作
  • 怎样只做自己的网站建设银行唐山分行网站
  • 咸阳鑫承网站建设软件开发公司网站模板
  • 百度怎么免费做网站网站建设大作业有代码
  • 小说素材网站设计素材网站特点
  • 如何建设一个好的网站WordPress主题设置数据库
  • 网站被模仿十堰网站制作公司
  • 怎么样做免费网站个人网站备案幕布
  • 做ppt的动图下载哪些网站制作一个网站需要多少时间
  • 公司网站开发制作备案中的网站
  • 怎么看网站的收录网站开发先前台和后台
  • 合肥市做网站多少钱wordpress网站布置视频
  • 中国建设人才网信息网站软件外包公司好不好
  • 网站建设与管理 市场分析上海网站建设公司排名
  • 怎么将公司网站设成首页网址关键词查询网站
  • 怎么用ps做网站ui邱县专业做网站
  • 国开行网站毕业申请怎么做大连旅顺口旅游攻略
  • 鲜花店网站源码成都专做婚介网站的公司
  • 合肥企业网站建设工哈尔滨公告