The core of a Java Bean Factory explained

The core of a Java Bean Factory explained

A bean factory converts a generic object like a map, a JSON object, an XML object to a specific bean object. For example for a JSON bean factory the createBean function looks like this :

static public Object createBean(Class<?> beanClass, JSONObject jsonObject) throws JSONException {

This function creates a bean value from a bean class and a JSON object. It loops over all properties of the bean class :

BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {

And for each bean property searches for a JSONObject property with the same name :

while (jsonPropertyNamesIterator.hasNext()) {
	String jsonPropertyName = jsonPropertyNamesIterator.next();
	if (!propertyName.equals(jsonPropertyName)) {
		continue;
	}

When found the value of the property is retrieved from the generic object and stored in the bean property:

// get value from jsonObject
Object value = getBeanPropertyValueFromJSONObject(beanClass, jsonObject, 
    propertyName);

// set value in the bean
setBeanPropertyValue(bean, propertyDescriptor, value);

The getBeanPropertyValueFromJSONObject creates a bean property value from :

  1. a beanClass
  2. a JSON object
  3. the descriptor of a property to retrieve
public static Object getBeanPropertyValueFromJSONObject(Class<?> beanClass, JSONObject jsonObject, String propertyName) 
        ?throws JSONException, IntrospectionException {

It first retrieves the generic property value from the JSON object :

Object jsonObjectPropertyValue = jsonObject.get(propertyName);

Then gets the class of the property in the bean class :

Class<?> propertyClass = 
    ReflectionUtil.getPropertyClass(propertyName, beanClass);

Then returns the bean value from the JSON object property value with the function :

return getBeanValueFromJSONObjectValue(propertyClass, jsonObjectPropertyValue);

The getBeanValueFromJSONObjectValue returns a bean value from 2 parameters :

  1. a bean class
  2. a JSON object
private static <T> Object getBeanValueFromJSONObjectValue( ?Class<?> beanValueClass, Object jsonObjectValue) 
    ?throws NoSuchFieldException, JSONException {

First the type of the jsonObjectValue input parameter is checked:

  1. if it symbolizes a null value, a bean value of null is returned
  2. if it is a JSONObject, a bean by calling recursively the createBean method (see above)
  3. if is a JSONArray a typed array or typed container is created depending on the bean class value. When it is an array it is interesting to see how generics coma into play :
JSONArray jsonArray = (JSONArray) jsonObjectValue;
int length = jsonArray.length();
ArrayList<Class<?>> types = jsonArray.getTypes();
ArrayList<Object> items = jsonArray.getItems();

?if (beanValueClass.isArray()) {
	Class<?> componentType = beanValueClass.getComponentType();
	T[] typedArray = (T[]) Array.newInstance(componentType, length);
	for (int i = 0; i < types.size(); i++) {
		Class<?> type = types.get(i);
		Object jsonObjectItemValue = items.get(i);
		Object beanItemValue = getBeanValueFromJSONObjectValue(type, 
            jsonObjectItemValue);
		typedArray[i] = (T) beanItemValue;
	}
	beanValue = typedArray;
}
 
  

The getBeanValueFromJSONObjectValue function is recursively called for each item of the JSONArray. Each value returned is casted with the generic parameter T which corresponds to the component type of the array:

Class<?> componentType = beanValueClass.getComponentType();
T[] typedArray = (T[]) Array.newInstance(componentType, length);

...

typedArray[i] = (T) beanItemValue;
 
  




要查看或添加评论,请登录

社区洞察

其他会员也浏览了