我想更改出现在复杂bean中许多地方的自定义类型的属性。使用Java8+,spring。。。欢迎提出任何意见。
这里有一个例子:我想定一个特定行业每个人的工资 Holding
至 42000)
:
class Employee {
String name;
int salary; // <-- I'd like to have an action on this field, everywhere
}
豆子:
class Holding {
Employee bigBoss;
List<Employee> workers;
Company partnership;
List<Company> ownedCompanies;
}
中间豆之一:
class Company {
Employee localBoss;
List<Employee> workers;
List<Company> childCompanies;
}
(都在同一个包裹里 my.own.package
(有二传手/吹手)
理想情况下,我想要的签名应该是(不编译):
<T> deepModifyBean( T beanToModify, Class<?> propertiesToModify , * value Supplier * ) ;
// and I would call it like :
Holding deepModifyBean( acmeBigCorp, Employee.class, (e -> e.setSalary( 42000 ) ) );
我试着用Spring BeanWrapper
但最终未能正确设置它,因为我不知道它是否处理递归,以及是否添加了任何过度反射。下面是我使用反射得到的结果(也是一些递归函数)
<T> void recurseModify( T obj, int newSalary ) {
Class<?> clazz = obj.getClass();
// if it is neither a collection or one of our class => next
if ( ! Iterable.class.isAssignableFrom(clazz) && ! clazz.getPackageName().startsWith("my.own.package") )
return;
// for each field of the class , see what to do.
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true); // to be able to read/write in it, bypass visibility...
Class<?> fieldType = field.getType();
// The one we want to modify
if (Employee.class.isAssignableFrom(fieldType)) {
Employee emp = (Employee) field.get(obj);
emp.setSalary( newSalary ); // overwrite salary
field.set(obj, emp);
// it is one of ours ? then it's worth checking the inside.
} else if (fieldType.getPackageName().startsWith("my.own.package")) {
recurseModify(obj, newSalary);
// go check in Lists
} else if (Iterable.class.isAssignableFrom(fieldType)) {
Iterator itr = ((Iterable) field.get(obj)).iterator();;
while (itr.hasNext()) {
recurseModify(itr.next(), newSalary);
}
}
}
}
我发现它很难阅读,而且它看起来像是一个常见的问题,已经被其他人用“正确的方法”解决了。有没有更好的方法(必须有),使用最新的框架?
暂无答案!
目前还没有任何答案,快来回答吧!