Springframework的BeanUtils.copyProperties原理源码浅层解析

本文介绍了Spring的BeanUtils.copyProperties方法的工作原理,涉及JavaBean的内省技术,探讨了内省缓存与ClassLoader的关系,以及Spring如何处理类加载器关闭时的内存回收问题。同时,文中给出了作者对源码的浅层分析,讨论了忽略属性的处理和反射的使用。
摘要由CSDN通过智能技术生成

新手原创,不喜轻喷,欢迎交流。       

       最近项目交付了,想着项目中遇到的一个问题,在传递返回的包装类给app端的时候有的字段位是null,如果这个字段app端需要其中的值,如果获取的值是null的时候会导致app的闪退,为了解决这个问题,我不得不把所有需要传递给app端且有可能为空的字段一个一个赋“”或者0等,为了简便,我把返回的包装类的数据类型只保留String和Integer.写出了以下方法:

@SuppressWarnings("unused")
public class ParameterInit {
public static <E> void inChange2(Object o) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchMethodException, SecurityException {
Class<? extends Object> c = o.getClass();                //获取要返回的类的class
Method[] methods = c.getMethods();                     //获取其中的方法(自定义的方法都是public)
for (Method m : methods) {
String methodName = m.getName();                //获取方法名
if(methodName.startsWith("set")) {                    //判断方法前缀(整个操作只有set/get有关)
String getMethod = methodName.substring(3);        //截取除set外的其余部分
Method method = c.getMethod("get"+getMethod );       //拼成get就变成了这个属性的get方法
Object invoke = method.invoke(o);             //因为get方法是没有参数的,所以直接传obj进去运行方法

if( invoke == null ) {                //判断当前方法的返回值

Type[] genericParameterTypes = m.getGenericParameterTypes();    //获取set方法的参数类型

if( genericParameterTypes[0] == String.class) {            //匹配参数类型
m.invoke(o, "");                        //如果是String类型就赋值“”
}else if( genericParameterTypes[0] == Integer.class) {    
m.invoke(o, 0);                        //如果是Integer类型就赋值0
}
}
}
}
System.out.println(o.toString());   //测试用,打印看是否所有字段都不为null
}

}

注:以上操作的参数Object是经过springframework的BeanUtils.copyProperties赋值过后的类

做完这些之后高兴的和领导说了一下我做了一个工具类,然后领导说就这个问题把copyProperties研究一下,做一个类似的吧

下面就说说对copyProperties的研究心得,做为一个新手,写的不好大家不要喷,谢谢

先说一下spring源在下载,用git下的方式是

git clone https://github.com/spring-projects/spring-framework.git

spring源码是用gradle写的,所以需要用gradle编译才能放到eclipse中,gradle安装这个大家百度吧

然后用gradle编译的命令是 gradle cleanidea eclipse

以下是copyProperties的源码

        public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, null, (String[]) null);

}

可以看到,这里面只是一个方法的调用

private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)
throws BeansException {
Assert.notNull(source, "Source must not be null");

Assert.notNull(target, "Target must not be null");

Class<?> actualEditable = target.getClass();
if (editable != null) {
if (!editable.isInstance(target)) {
throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
"] not assignable to Editable class [" + editable.getName() + "]");
}
actualEditable = editable;
}
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);

for (PropertyDescriptor targetPd : targetPds) {
BeanUtils.copyProperties()是一个常用的Java工具方法,它用于将一个Java对象的属性值复制到另一个Java对象中。该方法属于Apache Commons BeanUtils库,提供了简便的方式来复制对象的属性。 使用BeanUtils.copyProperties()方法,你可以将源对象的属性值复制到目标对象中,前提是这两个对象的属性名和类型相匹配。 以下是使用BeanUtils.copyProperties()方法的示例代码: ```java import org.apache.commons.beanutils.BeanUtils; public class Main { public static void main(String[] args) { SourceObject source = new SourceObject(); source.setFoo("Hello"); DestinationObject destination = new DestinationObject(); try { BeanUtils.copyProperties(destination, source); System.out.println(destination.getFoo()); // 输出:Hello } catch (Exception e) { e.printStackTrace(); } } } class SourceObject { private String foo; public String getFoo() { return foo; } public void setFoo(String foo) { this.foo = foo; } } class DestinationObject { private String foo; public String getFoo() { return foo; } public void setFoo(String foo) { this.foo = foo; } } ``` 在上面的示例中,我们创建了一个源对象source和一个目标对象destination,然后使用BeanUtils.copyProperties()方法将source对象的属性值复制到destination对象中。最后,打印出destination对象的属性值,可以看到它与source对象的属性值相同。 需要注意的是,BeanUtils.copyProperties()方法使用反射机制来实现属性值的复制,因此性能可能不如手动编写复制代码。另外,它只会复制两个对象相同的属性,如果目标对象有额外的属性,不会被赋值。如果需要更灵活的属性复制方式,可以考虑其他库或手动编写代码来实现
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值