Mybatis反射核心類Reflector的實現(xiàn)
Reflector類負責對一個類進行反射解析,并將解析后的結(jié)果在屬性中存儲起來。
一個類反射解析后都有哪些屬性呢?我們可以通過Reflector類定義的屬性來查看
public class Reflector { // 要被反射解析的類 private final Class<?> type; // 可讀屬性列表即有g(shù)et方法的屬性列表 private final String[] readablePropertyNames; // 可寫屬性列表即有set方法的屬性列表 private final String[] writeablePropertyNames; // set方法映射表。鍵為屬性名,值為對應的set方法 private final Map<String, Invoker> setMethods = new HashMap<String, Invoker>(); // get方法映射表。鍵為屬性名,值為對應的get方法 private final Map<String, Invoker> getMethods = new HashMap<String, Invoker>(); // set方法輸入?yún)?shù)類型映射表。鍵為屬性名,值為對應set方法輸入?yún)?shù)類型的Class private final Map<String, Class<?>> setTypes = new HashMap<String, Class<?>>(); // get方法返回值類型映射表。鍵為屬性名,值為對應get方法返回值類型的Class private final Map<String, Class<?>> getTypes = new HashMap<String, Class<?>>(); // 默認構(gòu)造器 private Constructor<?> defaultConstructor; // 忽略大小寫的屬性映射表。鍵為屬性名全大寫值,值為屬性名 private Map<String, String> caseInsensitivePropertyMap = new HashMap<String, String>(); // Reflector類反射解析一個類的過程是由構(gòu)造函數(shù)觸發(fā)的 public Reflector(Class<?> clazz) { // 記錄被反射解析的類 type = clazz; // 解析默認造方法 addDefaultConstructor(clazz); // 解析所有的getter addGetMethods(clazz); // 解析所有的setter addSetMethods(clazz); // 解析所有屬性 addFields(clazz); // 獲取可讀屬性列表 readablePropertyNames = getMethods.keySet().toArray(new String[getMethods.keySet().size()]); // 獲取可寫屬性列表 writeablePropertyNames = setMethods.keySet().toArray(new String[setMethods.keySet().size()]); // 獲取忽略大小寫的屬性列表 for (String propName : readablePropertyNames) { caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } for (String propName : writeablePropertyNames) { caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } } ..... }
創(chuàng)建方式:
1、直接new Reflector reflector = new Reflector(User.class); 2、工廠創(chuàng)建 ReflectorFactory reflectorFactory = new DefaultReflectorFactory(); Reflector reflector = reflectorFactory.findForClass(User.class);
對外暴露的方法:
Reflector reflector = new Reflector(User.class); // 獲取被解析反射的類 Class<?> type = reflector.getType(); // 根據(jù)屬性名獲取對應的set方法 Invoker setInvoker = reflector.getSetInvoker("name"); // 根據(jù)屬性名獲取對應的get方法 Invoker getInvoker = reflector.getGetInvoker("name"); // 獲取所有可讀屬性列表 String[] getablePropertyNames = reflector.getGetablePropertyNames(); // 獲取所有可寫屬性列表 String[] setablePropertyNames = reflector.getSetablePropertyNames(); // 獲取默認構(gòu)造器 Constructor<?> defaultConstructor = reflector.getDefaultConstructor(); // 根據(jù)屬性名獲取對應get方法返回值類型 Class<?> getterType = reflector.getGetterType("name"); // 根據(jù)屬性名獲取對應set方法參數(shù)類型 Class<?> setterType = reflector.getSetterType("name"); // 根據(jù)屬性名不區(qū)分大小寫獲取屬性名 String name = reflector.findPropertyName("name"); // 判斷屬性是否存在getter方法 boolean hasGetter = reflector.hasGetter("name"); // 判斷屬性是否存在getter方法 boolean hasSetter = reflector.hasSetter("name");
測試案例:
@Test public void test1()throws Exception{ Reflector reflector = new Reflector(User.class); Class<?> type = reflector.getType(); System.out.println("要被反射解析的類:"+type); Constructor<?> defaultConstructor = reflector.getDefaultConstructor(); System.out.println(defaultConstructor); String[] getablePropertyNames = reflector.getGetablePropertyNames(); for (String propertyName : getablePropertyNames) { System.out.println("可讀屬性:"+propertyName); } System.out.println("----------------------------------------------------------"); String[] setablePropertyNames = reflector.getSetablePropertyNames(); for (String propertyName : setablePropertyNames) { System.out.println("可寫屬性:"+propertyName); } System.out.println("--------------------------------------------------"); for (String propertyName : reflector.getGetablePropertyNames()) { Invoker name = reflector.getGetInvoker(propertyName); Object invoke = name.invoke(new User(), null); System.out.println("執(zhí)行屬性"+propertyName+"的get方法:"+invoke); } }
測試結(jié)果:
該類里面還有一個值的注意的小工具類可以直接拿來使用,生成方法簽名
private String getSignature(Method method) { StringBuilder sb = new StringBuilder(); Class<?> returnType = method.getReturnType(); if (returnType != null) { sb.append(returnType.getName()).append('#'); } sb.append(method.getName()); Class<?>[] parameters = method.getParameterTypes(); for (int i = 0; i < parameters.length; i++) { if (i == 0) { sb.append(':'); } else { sb.append(','); } sb.append(parameters[i].getName()); } return sb.toString(); }
到此這篇關(guān)于Mybatis反射核心類Reflector的實現(xiàn)的文章就介紹到這了,更多相關(guān)Mybatis反射核心類Reflector內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
CommonMark 使用教程:將 Markdown 語法轉(zhuǎn)成 Html
這篇文章主要介紹了CommonMark 使用教程:將 Markdown 語法轉(zhuǎn)成 Html,這個技巧我們做任何網(wǎng)站都可以用到,而且非常好用。,需要的朋友可以參考下2019-06-06mybatis-plus動態(tài)數(shù)據(jù)源讀寫分離方式
在分布式項目開發(fā)中,動態(tài)數(shù)據(jù)源的配置與使用至關(guān)重要,通過創(chuàng)建DynamicDatasourceService,實現(xiàn)數(shù)據(jù)源的動態(tài)添加與調(diào)用,有效管理主從庫操作,減輕數(shù)據(jù)庫壓力,此外,通過配置類與@DS注解,實現(xiàn)了靈活的分庫查詢功能,為高效處理數(shù)據(jù)提供了強有力的支持2024-10-10Java之使用POI教你玩轉(zhuǎn)Excel導入與導出
這篇文章主要介紹了Java之使用POI教你玩轉(zhuǎn)Excel導入與導出,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10