博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mybatis源码阅读-初始化六个工具(六)
阅读量:5328 次
发布时间:2019-06-14

本文共 22389 字,大约阅读时间需要 74 分钟。

六个基本工具图集

图片来源:

ObjectFactory

类图

接口定义

public interface ObjectFactory {    void setProperties(Properties var1);    
T create(Class
var1);
T create(Class
var1, List
> var2, List
var3);
boolean isCollection(Class
var1);}

 

使用方式

ObjectFactory objectFactory=new DefaultObjectFactory();        List
classesList=objectFactory.create(ArrayList.class); Classes classes = objectFactory.create(Classes.class); classes.setName("一年级"); classesList.add(classes);

DefaultObjectFactory

比较简单 我们可以直接拿来自己使用

public class DefaultObjectFactory implements ObjectFactory, Serializable {    private static final long serialVersionUID = -8855120656740914948L;    public DefaultObjectFactory() {    }    /**     * 创建指定类型的对象 不使用构造函数创建     * @param type 类型     * @param 
* @return */ public
T create(Class
type) { return this.create(type, (List)null, (List)null); } /** * 创建指定类型的对象 * @param type 类型 * @param constructorArgTypes 构造函数参数类型列表 * @param constructorArgs 构造函数参数列表 * @param
* @return */ public
T create(Class
type, List
> constructorArgTypes, List
constructorArgs) { Class
classToCreate = this.resolveInterface(type); return this.instantiateClass(classToCreate, constructorArgTypes, constructorArgs); } public void setProperties(Properties properties) { }
T instantiateClass(Class
type, List
> constructorArgTypes, List
constructorArgs) { try { Constructor constructor; //判断是否指定了构造函数初始化 if (constructorArgTypes != null && constructorArgs != null) { //获得private或public指定参数类型列表的构造函数 注:getConstructor和getDeclaredConstructor的区别是只能获得public constructor = type.getDeclaredConstructor((Class[])constructorArgTypes.toArray(new Class[constructorArgTypes.size()])); //如果是私有的 设置可以访问 if (!constructor.isAccessible()) { constructor.setAccessible(true); } return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()])); } else { constructor = type.getDeclaredConstructor(); if (!constructor.isAccessible()) { constructor.setAccessible(true); } return constructor.newInstance(); } } catch (Exception var9) { StringBuilder argTypes = new StringBuilder(); if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) { Iterator i$ = constructorArgTypes.iterator(); while(i$.hasNext()) { Class
argType = (Class)i$.next(); argTypes.append(argType.getSimpleName()); argTypes.append(","); } argTypes.deleteCharAt(argTypes.length() - 1); } StringBuilder argValues = new StringBuilder(); if (constructorArgs != null && !constructorArgs.isEmpty()) { Iterator i$ = constructorArgs.iterator(); while(i$.hasNext()) { Object argValue = i$.next(); argValues.append(String.valueOf(argValue)); argValues.append(","); } argValues.deleteCharAt(argValues.length() - 1); } throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + var9, var9); } } /** * 如果是定义结合类型 类型改为实现类 * @param type * @return */ protected Class
resolveInterface(Class
type) { Class classToCreate; if (type != List.class && type != Collection.class && type != Iterable.class) { if (type == Map.class) { classToCreate = HashMap.class; } else if (type == SortedSet.class) { classToCreate = TreeSet.class; } else if (type == Set.class) { classToCreate = HashSet.class; } else { classToCreate = type; } } else { classToCreate = ArrayList.class; } return classToCreate; } public
boolean isCollection(Class
type) { return Collection.class.isAssignableFrom(type); }}

ReflectorFactory

作用

创建reflector并缓存起来

类图

接口定义

public interface ReflectorFactory {    boolean isClassCacheEnabled();    void setClassCacheEnabled(boolean var1);    Reflector findForClass(Class
var1);}

DefaultReflectorFactory

public class DefaultReflectorFactory implements ReflectorFactory {    private boolean classCacheEnabled = true;    //将反射的元数据信息封装保存到Reflector 大大提交了性能    private final ConcurrentMap
, Reflector> reflectorMap = new ConcurrentHashMap(); public DefaultReflectorFactory() { } public boolean isClassCacheEnabled() { return this.classCacheEnabled; } public void setClassCacheEnabled(boolean classCacheEnabled) { this.classCacheEnabled = classCacheEnabled; } /** * 获得指定类型反射元数据信息 * @param type * @return */ public Reflector findForClass(Class
type) { if (this.classCacheEnabled) { Reflector cached = (Reflector)this.reflectorMap.get(type); //如果没有缓存则从缓存里面拿 if (cached == null) { cached = new Reflector(type); this.reflectorMap.put(type, cached); } return cached; } else { return new Reflector(type); } }}

Reflector

作用

封装反射的元数据信息

源码

public class Reflector {    private static final String[] EMPTY_STRING_ARRAY = new String[0];    private Class
type; private String[] readablePropertyNames; private String[] writeablePropertyNames; private Map
setMethods; private Map
getMethods; private Map
> setTypes; private Map
> getTypes; private Constructor
defaultConstructor; private Map
caseInsensitivePropertyMap; /** * 初始化并将对应的元数据信息封装起来 * @param clazz */ public Reflector(Class
clazz) { this.readablePropertyNames = EMPTY_STRING_ARRAY; this.writeablePropertyNames = EMPTY_STRING_ARRAY; //初始化几个map this.setMethods = new HashMap(); this.getMethods = new HashMap(); this.setTypes = new HashMap(); this.getTypes = new HashMap(); this.caseInsensitivePropertyMap = new HashMap(); this.type = clazz; //反射查找默认构造函数到defaultConstructor this.addDefaultConstructor(clazz); //反射获得所有的get方法元数据保存到以Invoker保存getMethods this.addGetMethods(clazz); //反射获得所有的set方法元数据以invokersetMethods this.addSetMethods(clazz); //反射获得所有的Fields元数据 this.addFields(clazz); this.readablePropertyNames = (String[])this.getMethods.keySet().toArray(new String[this.getMethods.keySet().size()]); this.writeablePropertyNames = (String[])this.setMethods.keySet().toArray(new String[this.setMethods.keySet().size()]); String[] arr$ = this.readablePropertyNames; int len$ = arr$.length; int i$; String propName; for(i$ = 0; i$ < len$; ++i$) { propName = arr$[i$]; this.caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } arr$ = this.writeablePropertyNames; len$ = arr$.length; for(i$ = 0; i$ < len$; ++i$) { propName = arr$[i$]; this.caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } } private void addDefaultConstructor(Class
clazz) { Constructor
[] consts = clazz.getDeclaredConstructors(); Constructor[] arr$ = consts; int len$ = consts.length; for(int i$ = 0; i$ < len$; ++i$) { Constructor
constructor = arr$[i$]; if (constructor.getParameterTypes().length == 0) { if (canAccessPrivateMethods()) { try { constructor.setAccessible(true); } catch (Exception var8) { ; } } if (constructor.isAccessible()) { this.defaultConstructor = constructor; } } } } private void addGetMethods(Class
cls) { Map
> conflictingGetters = new HashMap(); Method[] methods = this.getClassMethods(cls); Method[] arr$ = methods; int len$ = methods.length; for(int i$ = 0; i$ < len$; ++i$) { Method method = arr$[i$]; String name = method.getName(); if (name.startsWith("get") && name.length() > 3) { if (method.getParameterTypes().length == 0) { name = PropertyNamer.methodToProperty(name); this.addMethodConflict(conflictingGetters, name, method); } } else if (name.startsWith("is") && name.length() > 2 && method.getParameterTypes().length == 0) { name = PropertyNamer.methodToProperty(name); this.addMethodConflict(conflictingGetters, name, method); } } this.resolveGetterConflicts(conflictingGetters); } private void resolveGetterConflicts(Map
> conflictingGetters) { Iterator i$ = conflictingGetters.keySet().iterator(); while(true) { while(i$.hasNext()) { String propName = (String)i$.next(); List
getters = (List)conflictingGetters.get(propName); Iterator
iterator = getters.iterator(); Method firstMethod = (Method)iterator.next(); if (getters.size() == 1) { this.addGetMethod(propName, firstMethod); } else { Method getter = firstMethod; Class getterType = firstMethod.getReturnType(); while(iterator.hasNext()) { Method method = (Method)iterator.next(); Class
methodType = method.getReturnType(); if (methodType.equals(getterType)) { throw new ReflectionException("Illegal overloaded getter method with ambiguous type for property " + propName + " in class " + firstMethod.getDeclaringClass() + ". This breaks the JavaBeans " + "specification and can cause unpredicatble results."); } if (!methodType.isAssignableFrom(getterType)) { if (!getterType.isAssignableFrom(methodType)) { throw new ReflectionException("Illegal overloaded getter method with ambiguous type for property " + propName + " in class " + firstMethod.getDeclaringClass() + ". This breaks the JavaBeans " + "specification and can cause unpredicatble results."); } getter = method; getterType = methodType; } } this.addGetMethod(propName, getter); } } return; } } private void addGetMethod(String name, Method method) { if (this.isValidPropertyName(name)) { this.getMethods.put(name, new MethodInvoker(method)); Type returnType = TypeParameterResolver.resolveReturnType(method, this.type); this.getTypes.put(name, this.typeToClass(returnType)); } } private void addSetMethods(Class
cls) { Map
> conflictingSetters = new HashMap(); Method[] methods = this.getClassMethods(cls); Method[] arr$ = methods; int len$ = methods.length; for(int i$ = 0; i$ < len$; ++i$) { Method method = arr$[i$]; String name = method.getName(); if (name.startsWith("set") && name.length() > 3 && method.getParameterTypes().length == 1) { name = PropertyNamer.methodToProperty(name); this.addMethodConflict(conflictingSetters, name, method); } } this.resolveSetterConflicts(conflictingSetters); } private void addMethodConflict(Map
> conflictingMethods, String name, Method method) { List
list = (List)conflictingMethods.get(name); if (list == null) { list = new ArrayList(); conflictingMethods.put(name, list); } ((List)list).add(method); } private void resolveSetterConflicts(Map
> conflictingSetters) { Iterator i$ = conflictingSetters.keySet().iterator(); while(true) { while(i$.hasNext()) { String propName = (String)i$.next(); List
setters = (List)conflictingSetters.get(propName); Method firstMethod = (Method)setters.get(0); if (setters.size() == 1) { this.addSetMethod(propName, firstMethod); } else { Class
expectedType = (Class)this.getTypes.get(propName); if (expectedType == null) { throw new ReflectionException("Illegal overloaded setter method with ambiguous type for property " + propName + " in class " + firstMethod.getDeclaringClass() + ". This breaks the JavaBeans " + "specification and can cause unpredicatble results."); } Iterator
methods = setters.iterator(); Method setter = null; while(methods.hasNext()) { Method method = (Method)methods.next(); if (method.getParameterTypes().length == 1 && expectedType.equals(method.getParameterTypes()[0])) { setter = method; break; } } if (setter == null) { throw new ReflectionException("Illegal overloaded setter method with ambiguous type for property " + propName + " in class " + firstMethod.getDeclaringClass() + ". This breaks the JavaBeans " + "specification and can cause unpredicatble results."); } this.addSetMethod(propName, setter); } } return; } } private void addSetMethod(String name, Method method) { if (this.isValidPropertyName(name)) { this.setMethods.put(name, new MethodInvoker(method)); Type[] paramTypes = TypeParameterResolver.resolveParamTypes(method, this.type); this.setTypes.put(name, this.typeToClass(paramTypes[0])); } } private Class
typeToClass(Type src) { Class
result = null; if (src instanceof Class) { result = (Class)src; } else if (src instanceof ParameterizedType) { result = (Class)((ParameterizedType)src).getRawType(); } else if (src instanceof GenericArrayType) { Type componentType = ((GenericArrayType)src).getGenericComponentType(); if (componentType instanceof Class) { result = Array.newInstance((Class)componentType, 0).getClass(); } else { Class
componentClass = this.typeToClass(componentType); result = Array.newInstance(componentClass, 0).getClass(); } } if (result == null) { result = Object.class; } return result; } private void addFields(Class
clazz) { Field[] fields = clazz.getDeclaredFields(); Field[] arr$ = fields; int len$ = fields.length; for(int i$ = 0; i$ < len$; ++i$) { Field field = arr$[i$]; if (canAccessPrivateMethods()) { try { field.setAccessible(true); } catch (Exception var8) { ; } } if (field.isAccessible()) { if (!this.setMethods.containsKey(field.getName())) { int modifiers = field.getModifiers(); if (!Modifier.isFinal(modifiers) || !Modifier.isStatic(modifiers)) { this.addSetField(field); } } if (!this.getMethods.containsKey(field.getName())) { this.addGetField(field); } } } if (clazz.getSuperclass() != null) { this.addFields(clazz.getSuperclass()); } } private void addSetField(Field field) { if (this.isValidPropertyName(field.getName())) { this.setMethods.put(field.getName(), new SetFieldInvoker(field)); Type fieldType = TypeParameterResolver.resolveFieldType(field, this.type); this.setTypes.put(field.getName(), this.typeToClass(fieldType)); } } private void addGetField(Field field) { if (this.isValidPropertyName(field.getName())) { this.getMethods.put(field.getName(), new GetFieldInvoker(field)); Type fieldType = TypeParameterResolver.resolveFieldType(field, this.type); this.getTypes.put(field.getName(), this.typeToClass(fieldType)); } } private boolean isValidPropertyName(String name) { return !name.startsWith("$") && !"serialVersionUID".equals(name) && !"class".equals(name); } private Method[] getClassMethods(Class
cls) { Map
uniqueMethods = new HashMap(); for(Class currentClass = cls; currentClass != null; currentClass = currentClass.getSuperclass()) { this.addUniqueMethods(uniqueMethods, currentClass.getDeclaredMethods()); Class
[] interfaces = currentClass.getInterfaces(); Class[] arr$ = interfaces; int len$ = interfaces.length; for(int i$ = 0; i$ < len$; ++i$) { Class
anInterface = arr$[i$]; this.addUniqueMethods(uniqueMethods, anInterface.getMethods()); } } Collection
methods = uniqueMethods.values(); return (Method[])methods.toArray(new Method[methods.size()]); } private void addUniqueMethods(Map
uniqueMethods, Method[] methods) { Method[] arr$ = methods; int len$ = methods.length; for(int i$ = 0; i$ < len$; ++i$) { Method currentMethod = arr$[i$]; if (!currentMethod.isBridge()) { String signature = this.getSignature(currentMethod); if (!uniqueMethods.containsKey(signature)) { if (canAccessPrivateMethods()) { try { currentMethod.setAccessible(true); } catch (Exception var9) { ; } } uniqueMethods.put(signature, currentMethod); } } } } 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(); } private static boolean canAccessPrivateMethods() { try { SecurityManager securityManager = System.getSecurityManager(); if (null != securityManager) { securityManager.checkPermission(new ReflectPermission("suppressAccessChecks")); } return true; } catch (SecurityException var1) { return false; } } public Class
getType() { return this.type; } public Constructor
getDefaultConstructor() { if (this.defaultConstructor != null) { return this.defaultConstructor; } else { throw new ReflectionException("There is no default constructor for " + this.type); } } public boolean hasDefaultConstructor() { return this.defaultConstructor != null; } public Invoker getSetInvoker(String propertyName) { Invoker method = (Invoker)this.setMethods.get(propertyName); if (method == null) { throw new ReflectionException("There is no setter for property named '" + propertyName + "' in '" + this.type + "'"); } else { return method; } } public Invoker getGetInvoker(String propertyName) { Invoker method = (Invoker)this.getMethods.get(propertyName); if (method == null) { throw new ReflectionException("There is no getter for property named '" + propertyName + "' in '" + this.type + "'"); } else { return method; } } public Class
getSetterType(String propertyName) { Class
clazz = (Class)this.setTypes.get(propertyName); if (clazz == null) { throw new ReflectionException("There is no setter for property named '" + propertyName + "' in '" + this.type + "'"); } else { return clazz; } } public Class
getGetterType(String propertyName) { Class
clazz = (Class)this.getTypes.get(propertyName); if (clazz == null) { throw new ReflectionException("There is no getter for property named '" + propertyName + "' in '" + this.type + "'"); } else { return clazz; } } public String[] getGetablePropertyNames() { return this.readablePropertyNames; } public String[] getSetablePropertyNames() { return this.writeablePropertyNames; } public boolean hasSetter(String propertyName) { return this.setMethods.keySet().contains(propertyName); } public boolean hasGetter(String propertyName) { return this.getMethods.keySet().contains(propertyName); } public String findPropertyName(String name) { return (String)this.caseInsensitivePropertyMap.get(name.toUpperCase(Locale.ENGLISH)); }}

 Invoker

作用

用于封装方法filed设置的值的动作

类图

接口定义

public interface Invoker {    Object invoke(Object var1, Object[] var2) throws IllegalAccessException, InvocationTargetException;    Class
getType();}

SetFieldInvoker

/** * 封装filed元数据信息 */public class SetFieldInvoker implements Invoker {    private Field field;    public SetFieldInvoker(Field field) {        this.field = field;    }    //给指定对象的当前属性设置值    public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {        this.field.set(target, args[0]);        return null;    }    public Class
getType() { return this.field.getType(); }}

GetFieldInvoker

/** * 封装Filed信息 提供getfiled的调用实现 */public class GetFieldInvoker implements Invoker {    private Field field;    public GetFieldInvoker(Field field) {        this.field = field;    }    public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {        return this.field.get(target);    }    public Class
getType() { return this.field.getType(); }}

MethodInvoker

/** * 方法元数据封装 以及提供调用的方法 */public class MethodInvoker implements Invoker {    private Class
type; private Method method; public MethodInvoker(Method method) { this.method = method; if (method.getParameterTypes().length == 1) { this.type = method.getParameterTypes()[0]; } else { this.type = method.getReturnType(); } } public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException { return this.method.invoke(target, args); } public Class
getType() { return this.type; }}

 反射工具的使用

//对象创建工厂        ObjectFactory objectFactory=new DefaultObjectFactory();        //反射创建ArrayList        List
classesList=objectFactory.create(ArrayList.class); //反射类创建工厂 必须单例哟 ReflectorFactory reflectorFactory= new DefaultReflectorFactory(); Classes classes = objectFactory.create(Classes.class); //获得Classes所有filed和get的元数据封装信息 并缓存 下次再次获取就是使用缓存 Reflector classesReflector= reflectorFactory.findForClass(Classes.class); //获得对应Filed或者setMethod的Invoker封装并调用设置值 classesReflector.getSetInvoker("name").invoke(classes,new Object[]{"一年级"}); classesList.add(classes); for (Classes item: classesList) { System.out.print(item.getName()); }

 

XPath、EntityResolver

说明

解析xml使用非mybatis内部工具类 就不贴源码了

使用方式

1.解析如下xml

insert INTO classes(name) VALUES (#{name});
UPDATE classes set name=#{name} where id=#{id};
delete from classes where id=#{id};

2.代码

public static  void parseXml() throws IOException, ParserConfigurationException, SAXException, XPathExpressionException {        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();        builderFactory.setValidating(false);        DocumentBuilder builder = builderFactory.newDocumentBuilder();        //不加这句话默认会去http://mybatis.org/dtd/mybatis-3-config.dtd 加上的话 会从本地dtd查找        builder.setEntityResolver(new XMLMapperEntityResolver());        InputSource inputSource = new InputSource(Resources.getResourceAsStream("ClassesMapper.xml"));        Document document = builder.parse(inputSource);        XPathFactory xPathFactory = XPathFactory.newInstance();        XPath xpath = xPathFactory.newXPath();        //获得mapper节点的namespace的值        String value = (String) xpath.evaluate("/mapper/@namespace", document, XPathConstants.STRING);        System.out.println("namespace=\"" + value + "\"");        //获得mapper节点        Node mapperNode = (Node) xpath.evaluate("/mapper", document, XPathConstants.NODE);        NodeList nodeList= mapperNode.getChildNodes();        System.out.println(nodeList.getLength());        for(int i=0;i

 

转载于:https://www.cnblogs.com/LQBlog/p/10684742.html

你可能感兴趣的文章
H5多文本换行
查看>>
flask-script插件
查看>>
HAL层三类函数及其作用
查看>>
Odoo 去掉 恼人的 "上午"和"下午"
查看>>
web@h,c小总结
查看>>
USACO 3.2 msquare 裸BFS
查看>>
Naive and Silly Muggles (计算几何)
查看>>
java编程思想笔记(一)——面向对象导论
查看>>
nginx 出现504 Gateway Time-out的解决方法
查看>>
(HDU)1089 --A+B for Input-Output Practice (I)(输入输出练习(I))
查看>>
SQL Server 备份和还原
查看>>
Data Structure 基本概念
查看>>
微信内置浏览器不支持 onclick 如何解决?(原因是因为内面中的内容或者标签大部分是动态生成的)...
查看>>
Ubuntu改坏sudoers后无法使用sudo的解决办法
查看>>
记字符编码与转义符的纠缠
查看>>
NEYC 2017 游记
查看>>
【BZOJ 3669】 [Noi2014]魔法森林 LCT维护动态最小生成树
查看>>
[搬运] 写给 C# 开发人员的函数式编程
查看>>
对Python中yield的理解
查看>>
NailTech 公司网站制作思路
查看>>