这两天又看了看Rod Johnson的Expert one-on-one J2EE Without EJB。看到第七章是,看到bean属性动态赋值用到了java.beans.PropertyEditor觉得很想了解一下,于是通过重写一段原来的代码熟悉了java.beans API。感觉上这种实现方式规避了很多程序陷阱,而且可以让程序看起来更优雅。这里,我把重写的代码,跟对这种实现方式的看法表达出来。
首先说说需求。
根据类名生成一个实例我们现在叫他obj,一个Map(map中存储的是property key-value),把Map的值根据obj的property name赋给obj。
例如,obj有name,age两个属性并且曝露Javabean标准的存取属性的方法,map有 name=lh , age=11 两个键值对。
分析一下我们要做什么。
1,首先根据反射找出所有公开的存取方法,通过方法名跟map的key进行匹配,找出keyName。找出需要赋值的方法setMethod
2,根据setMethod的方法签名,找到接收参数的类型class.
3,把keyName的值keyValue得到,把keyValue转变成class类型。
4,调用setMethod。
下面是一段类型转换的代码。
static Object getValue(Object v, Class type) {
if (type.getName().equals(String.class.getName())) {
return v.toString();
} else if (type.getName().equals(Long.class.getName())) {
return new Long(v.toString());
} else if (type.getName().equals(Integer.class.getName())) {
return new Integer(v.toString());
} else if (type.getName().equals(Double.class.getName())) {
return new Double(v.toString());
} else if (type.getName().equals(Date.class.getName())) {
return java.sql.Date.valueOf(v.toString());
} else if (type.getName().equals(long.class.getName())) {
return new Long(v.toString());
} else if (type.getName().equals(int.class.getName())) {
return new Integer(v.toString());
} else if (type.getName().equals(double.class.getName())) {
return new Double(v.toString());
}else if (type.getName().equals(BigDecimal.class.getName())) {
return new BigDecimal(v.toString());
} else {
return null;
}
}
这段代码的问题一目了然,每加入一个需要转换的类型就要修改这段代码,但是通过用java.beans API可以解决这个问题。
package com.surekam.util.reflection;
import java.beans.BeanInfo;
import java.beans.Expression;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.lang.reflect.Method;
import java.util.Properties;
import com.surekam.model.record.TobacOrder;
import test.util.TestXML;
/**
* 类说明:通过反射为bean赋值。
*
* @author 李华
*
*/
//
public class Evaluate { /** * 参数说明:*className :要赋值的bean的type**po:要赋值的bean,如果po为空则创建一个**prop:属性名->值** @author 李华 * */
public static Object evaluatePo(String className, Object po, Properties prop) {
try {
Class poClass = Class.forName(className);
if (po == null) {
po = poClass.newInstance();
}
// Introspector相当beans这个架构的一个入口。类似于Hibernate的SessionFactory// 通过bean的类型获得bean的描述—》获得属性描述的集合
BeanInfo bi = Introspector.getBeanInfo(poClass);
PropertyDescriptor[] pd = bi.getPropertyDescriptors();
for (int i = 0; i < pd.length; i++) {
if (prop.getProperty(pd[i].getName()) != null) {
Object value = getPropValue(pd[i].getPropertyType(),
prop.getProperty(pd[i].getName()));
executeEvaluate(po, pd[i].getWriteMethod(), value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return po;
}
// 这里是PropertyEditor 的使用,规避了if条件的使用。让代码的扩展性得到了很好的保证。这里使用的是依赖查找(DL)的方式。// 注册PropertyEditor 的步骤放在了bean容器当中 static Object getPropValue(Class clazz, String value)
throws InstantiationException, IllegalAccessException {
PropertyEditor pe = PropertyEditorManager.findEditor(clazz);
pe.setAsText(value);
return pe.getValue();
}
//调用赋值方法
static void executeEvaluate(Object dest, Method m, Object value)
throws Exception {
Expression e = new Expression(dest, m.getName(),
new Object[] { value });
e.execute();
}
}
总结一下PropertyEditor 的使用方式。 1,注册PropertyEditor 。通过PropertyEditorManager的registerEditor方法注册PropertyEditor。 2,查找PropertyEditor 。通过PropertyEditorManager的findEditor方法查找PropertyEditor。 3,转换值。调用PropertyEditor 的setAsText方法进行转换。用getValue方法获得值。 java.beans包是JDK对java reflection的封装。Expression 封装了方法调用的细节。BeanInfo ,PropertyDescriptor封装了查找属性的细节。规避了很多代码的陷阱,隐藏了很多reflection的实现细节。通过这个框架编写的代码,更加强壮,更加有扩展性。
分享到:
相关推荐
import java.beans.*; public class BeanConverter { public static <T> T convert(Map, String> parameters, Class<T> clazz) throws Exception { T bean = clazz.getDeclaredConstructor().newInstance(); ...
3. 在你的代码中,你可以通过`import java.beans.*;`引入所需类和接口。 使用`openbean.jar`和`java.beans`包可以帮助你在Android应用中实现一些高级功能,例如动态属性操作、事件处理和XML序列化。但是,需要注意...
Java反射中java.beans包学习总结 Java反射中java.beans包是一个非常重要的包,提供了许多有用的工具类和接口,帮助我们更好地实现Java对象的反射操作。本篇文章将通过学习Java反射中java.beans包,总结出相关的知识...
`java.beans.EventSetDescriptor` 描述了一个事件集,而 `java.beans.PropertyChangeEvent` 和 `java.beans.VetoableChangeEvent` 分别表示属性变化和可取消的变化事件。 4. **Listener**: 通过监听器接口,可以...
org.springframework.beans-3.0.5工程所需jar包,com.springsource.net.sf.cglib-2.2.0.jar、 com.springsource.org.apache.commons.logging-1.1.1.jar、 javax.inject.jar、 javax.servlet.jsp.jar、 org.spring...
JAVA API官方文档中文版软件包 java.applet java.awt java.awt.color ...java.beans.beancontext java.io java.lang java.lang.annotation java.lang.instrument java.lang.management java.lang.ref
org.springframework.beans-3.0.0.M4.jar
`org.springframework.beans.factory.config.PropertyPlaceholderConfigurer` 是Spring框架中的一个重要组件,主要负责处理配置文件中的占位符替换。这个类是Spring在初始化bean时用来解析和注入环境变量或系统属性...
org.springframework.beans-3.0.0.CI-331.jar的jar包下载,请安心使用。
中文版,平时开发超...java.beans.beancontext 提供与 bean 上下文有关的类和接口。 java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 ......
org.springframework.beans-3.1.0.RELEASE.jar
合适研究底层研发员,但,一般程序员也必须掌握的要点 JDK研究系列--java.beans
反射技术在Java中的应用非常广泛,例如在Java Beans、Java Servlet、Java Server Page等技术中都使用了反射技术。反射技术还可以用于实现动态代理、Aspect-Oriented Programming等技术。 反射技术的实现是基于Java...
由于它与AWT和Swing紧密依赖,因此无法轻易将其从java.desktop模块中删除,从而导致任何使用java.beans包的第三方库都依赖于所有java.desktop类。 java.desktop模块的额外开销使JVM安装增加了12mb的大小,并增加了...
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142) ... 38 more Caused by: java.lang.ClassNotFoundException: ...
轻巧,快速的java.beans.Introspector重新实现,用于消除对Bean Introspection的java.desktop模块的依赖。 问题 JDK 9中引入的模块封装了Java标准库中的所有AWT,Swing,Image和Sound软件包。 除此之外,它还包含带...
java.beans.beancontext 提供与 bean 上下文有关的类和接口。 java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 ...
org.springframework.beans.annotation org.springframework.beans.factory org.springframework.beans.factory.access org.springframework.beans.factory.access.el org.springframework.beans.factory.annotation...
at net.sf.cglib.beans.BeanCopier$Generator.generateClass(BeanCopier.java:133) at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) at ...
此外,Java标准库中的`java.beans.XMLEncoder`和`java.beans.XMLDecoder`也可以用来序列化和反序列化Java对象,但它们是针对XML的,而不是JSON。如果你需要处理JSON,还是要依赖第三方库。 总结起来,虽然Java反射...