본문 바로가기
  • A space that records me :)
Language/JAVA

[JAVA] PropertyDescriptor 클래스

by yjkim_97 2020. 11. 30.

하위클래스 : IndexedPropertyDescriptor

상위클래스 : FeatureDescriptor

 

PropertyDescriptor는 Object의 한쌍의 접근자 메서드(getMethod, setMethod)의 속성을 다루는 클래스이다.

A PropertyDescriptor describes one property that a Java Bean exports via a pair of accessor methods.

 

생성자

PropertyDescriptor(String propertyName, Class<?> beanClass)
get/set 접근자 메서드를 사용하는 속성에 대한 PropertyDescriptor를 구성한다.
PropertyDescriptor(String propertyName, Class<?> beanClass, String readMethodName, String writeMethodName)
간단한 속성의 이름과, 속성을 읽고 쓰기 위한 메서드의 이름을 사용한다.
PropertyDescriptor(String propertyName, Method readMethod, Method writeMethod)
단순 속성의 이름과, 속성을 읽고 쓰기위한 Method 개체를 사용한다.

 

대표 Method

Method 설명
getPropertyType  해당 get/set메소드가 다루는 객체 class 타입을 반환한다.
getReadMethod getMethod를 가져온다. 읽을 수 없는 속성인 경우 null을 리턴한다.
setReadMethod 새로운 getMethod를 선언한다.
getWriteMethod setMethod를 가져온다. 쓸수 없는 속성인 경우 null을 리턴한다.
setWriteMethod 새로운 setMethod를 선언한다.

 


사용 예제

getPropertyType()

    public static List<PropertyDescriptor> getPropertyDescriptors(Class<?> clazz)
    {

        List<PropertyDescriptor> propertyList = new ArrayList<>();
        
        try
        {
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
            if (beanInfo != null)
            {
                PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
                if (descriptors != null)
                {
                	// Object의 속성을 하나씩 돌림.
                    for (PropertyDescriptor descriptor : descriptors)
                    {
                    	// 각 속성타입을 체크 (Class면 생성자인가?)
                        if (descriptor.getPropertyType() == Class.class)
                        {
                            continue;
                        }
                        
                        // 생성자가 아닌 속성을 list에 넣는다.
                        // 결과적으로 생성자를 제외한 속성들의 get,set Method(PropertyDescriptor)가  list에 모인다.
                        // PropertyDescriptor는 하나의 속성의 get,set Method이다.
                        propertyList.add(descriptor);
                    }
                }
            }
        } catch (IntrospectionException e)
        {
            if (LOGGER.isWarnEnabled())
            {
                LOGGER.warn(e.getMessage(), e);
            }
        }

        return propertyList;
    }

 

getWriteMethod()

public static Object convertMapToObject(Map<String, String> map, Object objClass) {
    // Class 속성들의 PropertyDescriptor를 list로 추출함.
    List<PropertyDescriptor> propertyDescriptors = ReflectionUtil.getPropertyDescriptors(objClass.getClass());

    // ex. testClass.property -> new HashMap<>("property", new PrppertyDescriptor)
    // propertyDescriptors 리스트를 돌면서 Map list로 변환 (키 : 속성이름, 값 : PropertyDescriptor)
    Map<String, PropertyDescriptor> namePdMap = new HashMap<>();
    for (PropertyDescriptor pd : propertyDescriptors) {
        String pdName = pd.getName();
        namePdMap.put(pdName, pd);
    }


    for (Map.Entry<String, String> entry : map.entrySet()) {
        String key = entry.getKey(); // 속성 이름
        String val = entry.getValue(); // Object set으로 들어갈 속성 값.

    	PropertyDescriptor pd = namePdMap.get(key); // 속성의 PropertyDescriptor

    	Class<?> propertyType = pd.getPropertyType(); // 속성의 타입

    	Object resultValue = val;

        if (resultValue != null) {

            // Class의 getMethod 호출시 resultValue를 리턴하도록 작업(Method.invoke)
            invokeMethodSiently(objClass, pd.getWriteMethod(), resultValue);
        }
    }

    LOGGER.debug("Map To Model result >> " + objClass);
    return objClass;
}




// method의 get,set 접근자 사용
private static void invokeMethodSiently(Object obj, Method m, Object val) {
    try
    {
  		m.invoke(obj, val);
    } catch (Exception ex)
    {
    	LOGGER.error(ex.getMessage(), ex);
    }
}

getReadMethod()

public static Map<String, String> converObjectToMap(Object obj){
    try {
    	List<PropertyDescriptor> propertyDescriptors = ReflectionUtil.getPropertyDescriptors(obj.getClass());
    	Map<String, String> resultMap = new HashMap<String, String>();
    	for(PropertyDescriptor pd : propertyDescriptors) {
        
		// pd.getName() : 속성의 이름
        	// PropertyDescriptor의 접근자 get메소드를 이용하여, Object의 속성들을 get하여 map에 집어넣음
        	resultMap.put(pd.getName(), invokeGetMethod(obj, pd.getReadMethod()).toString());
    	}
    	return resultMap;
    } catch (IllegalArgumentException e) {
    	return null;
    }

}

참고 (Method invoke)


https://docs.oracle.com/javase/8/docs/api/java/beans/PropertyDescriptor.html

 

PropertyDescriptor (Java Platform SE 8 )

Constructs an instance of a property editor using the current property editor class. If the property editor class has a public constructor that takes an Object argument then it will be invoked using the bean parameter as the argument. Otherwise, the defaul

docs.oracle.com