内省、および内省の用途

17957 ワード

実際のプログラミングでは、Student、Employee、Orderなど、値オブジェクトをパッケージするためのクラスが必要になります.これらのクラスにはビジネスメソッドがないことがよくあります.処理する必要があるエンティティオブジェクトをパッケージするために、属性がプライベートであることが特徴です.パラメータの有無のpublic構造方法;プライベート属性に対して必要に応じて公有のgetXxxメソッドとsetXxxメソッドを提供する.たとえば、属性名がnameの場合、getNameメソッドは属性name値を返し、setNameメソッドはname値を設定します.注意方法の名前は通常getまたはsetに属性名を付け、属性名の頭文字を大文字にします.これらの方法をgetters/settersと呼ぶ.gettersには戻り値が必要でメソッドパラメータがありません.setter値には戻り値がなく、メソッドパラメータがあります.
これらの特徴に合致するクラスは、JavaBeanと呼ばれています.
内省(Inspector)メカニズムは反射の基礎に基づいて、Java言語のBeanクラスの属性、イベントに対するデフォルトの処理方法である.
注意:クラスにgetXXXメソッドがあるか、setXXXメソッドがあるか、または同時にgetXXXおよびsetXXXメソッドがある限り、getXXXメソッドにはメソッドパラメータがなく、戻り値があります.setXXXメソッドには戻り値がなく、メソッドパラメータがあります.では、内省メカニズムはXXXを属性としている.内省メカニズムで属性を検索する場合は、クラスで宣言された属性名ではなくgetterとsetterメソッドに基づいて属性名を確認します.
package com.yh.reflex;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

/**
 * --  
 *
 */
public class Demo03 {
	
	public static void main(String[] args)throws Exception {
		String className = "com.yh.reflex.Student";
		Class<?> cls = Class.forName(className);
		System.out.println(cls);
		
		BeanInfo studentInfo = Introspector.getBeanInfo(cls);
		PropertyDescriptor[] propertys = studentInfo.getPropertyDescriptors();//  ;get,set
		
		for(PropertyDescriptor p : propertys) {
			System.out.println(p.getName());
			System.out.println("\t"+p.getPropertyType());//    
			System.out.println("\t"+p.getReadMethod());//get  
			System.out.println("\t"+p.getWriteMethod());//set  
		}
	}
	
}


内省の用途:例えばJDBCで、内省の方式を通じてオブジェクトの間で属性の複製を行うことができます
package com.yh.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 *        ;   cn.hutool.core.bean.BeanUtil.copyProperties
 *
 */
public class BeanUtil {
	
	private BeanUtil() {}
	
	/**
	 * 
	 * @param sourceBean       ;  
	 * @param targetBean       ;  
	 * @param ignoreProperties         
	 */
	public static void copy(Object sourceBean,Object targetBean,String...ignoreProperties) {
		Set<String> ignorePropertiesSet = new HashSet<>();
		if(ignoreProperties!=null){
			java.util.Collections.addAll(ignorePropertiesSet, ignoreProperties);
		}
		Class<?> sourceClass = sourceBean.getClass();
		Class<?> targetClass = targetBean.getClass();
		try {
			BeanInfo sourceInfo = Introspector.getBeanInfo(sourceClass);
			PropertyDescriptor[] propertys = sourceInfo.getPropertyDescriptors();
			Map<String, PropertyDescriptor> map = new HashMap<String, PropertyDescriptor>();
			for(PropertyDescriptor p : propertys) {
				map.put(p.getName(), p);
			}
			BeanInfo targetInfo = Introspector.getBeanInfo(targetClass);
			propertys = targetInfo.getPropertyDescriptors();
			for(PropertyDescriptor p : propertys) {
				if(p.getWriteMethod()==null) {//    bean     setter,  ,       
					continue;
				}
				if(ignorePropertiesSet.contains(p.getName())) {//    bean          ,  
					continue;
				}
				PropertyDescriptor sourceProperty = map.get(p.getName());
				if(sourceProperty == null || sourceProperty.getReadMethod() == null) {//          getter  ,  
					continue;
				}
				//        ,                
				Object obj = sourceProperty.getReadMethod().invoke(sourceBean);
				//          
				if(obj != null) {
					p.getWriteMethod().invoke(targetBean, obj);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}