神刀安全网

mybatis 源码分析之 ObjectFactory 等

在 config.xml 当中有一个节点是 ObjectFactory 和 ObjectWrapperFactory:

 <objectFactory type="">   <property name="" value=""/>  </objectFactory>   <objectWrapperFactory type="">   <property name="" value=""/>  </objectWrapperFactory> 

MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。

ObjectFactory 接口很简单,它包含两个创建用的方法,一个是处理默认构造方法的,另外一个是处理带参数的构造方法的。 最后,setProperties 方法可以被用来配置 ObjectFactory,在初始化你的 ObjectFactory 实例后, objectFactory 元素体中定义的属性会被传递给 setProperties 方法。

public interface ObjectFactory {    void setProperties(Properties properties);    <T> T create(Class<T> type);    <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);    <T> boolean isCollection(Class<T> type); } 

一般不会自己创建 ObjectFactory,都会使用默认的 DefaultObjectFactory:

public class DefaultObjectFactory implements ObjectFactory, Serializable {    private static final long serialVersionUID = -8855120656740914948L;    @Override   public <T> T create(Class<T> type) {     return create(type, null, null);   }    @SuppressWarnings("unchecked")   @Override   public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {     Class<?> classToCreate = resolveInterface(type);     // we know types are assignable     return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);   }    @Override   public void setProperties(Properties properties) {     // no props for default   }    <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {     try {       Constructor<T> constructor;       if (constructorArgTypes == null || constructorArgs == null) {         constructor = type.getDeclaredConstructor();         if (!constructor.isAccessible()) {           constructor.setAccessible(true);         }         return constructor.newInstance();       }       constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));       if (!constructor.isAccessible()) {         constructor.setAccessible(true);       }       return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));     } catch (Exception e) {       StringBuilder argTypes = new StringBuilder();       if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) {         for (Class<?> argType : constructorArgTypes) {           argTypes.append(argType.getSimpleName());           argTypes.append(",");         }         argTypes.deleteCharAt(argTypes.length() - 1); // remove trailing ,       }       StringBuilder argValues = new StringBuilder();       if (constructorArgs != null && !constructorArgs.isEmpty()) {         for (Object argValue : constructorArgs) {           argValues.append(String.valueOf(argValue));           argValues.append(",");         }         argValues.deleteCharAt(argValues.length() - 1); // remove trailing ,       }       throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e);     }   }    protected Class<?> resolveInterface(Class<?> type) {     Class<?> classToCreate;     if (type == List.class || type == Collection.class || type == Iterable.class) {       classToCreate = ArrayList.class;     } else if (type == Map.class) {       classToCreate = HashMap.class;     } else if (type == SortedSet.class) { // issue #510 Collections Support       classToCreate = TreeSet.class;     } else if (type == Set.class) {       classToCreate = HashSet.class;     } else {       classToCreate = type;     }     return classToCreate;   }    @Override   public <T> boolean isCollection(Class<T> type) {     return Collection.class.isAssignableFrom(type);   }  } 

实现比较简单,先是通过 resolveInterface 来解析传递进来的 Class 类型,然后基于反射创建对象实例。

在上一篇分析当中,ParameterMappingTokenHandler 当中有一个属性 MetaObject 还没有分析,并且当中的 buildParameterMapping 方法也还没仔细分析,下面仔细分析这些内容。

MetaObject

ParameterMappingTokenHandler 的构造方法如下创建 MetaObject:

public ParameterMappingTokenHandler(Configuration configuration, Class<?> parameterType, Map<String, Object> additionalParameters) {       super(configuration);       this.parameterType = parameterType;       this.metaParameters = configuration.newMetaObject(additionalParameters);     }  //Configuration 当中的方法 public MetaObject newMetaObject(Object object) {     return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);   }  //MetaObject 当中的方法   public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {     if (object == null) {       return SystemMetaObject.NULL_META_OBJECT;     } else {       return new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);     }   } 

在 ParameterMappingTokenHandler 当中是通过 configuration 来创建的 MetaObject,而内部是通过 MetaObject 的静态方法来创建 MetaObject 的实例。那么继续看一下 MetaObject 里面的属性,以及构造方法:

private Object originalObject;   private ObjectWrapper objectWrapper;   private ObjectFactory objectFactory;   private ObjectWrapperFactory objectWrapperFactory;   private ReflectorFactory reflectorFactory;    private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {     this.originalObject = object;     this.objectFactory = objectFactory;     this.objectWrapperFactory = objectWrapperFactory;     this.reflectorFactory = reflectorFactory;      if (object instanceof ObjectWrapper) {       this.objectWrapper = (ObjectWrapper) object;     } else if (objectWrapperFactory.hasWrapperFor(object)) {       this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);     } else if (object instanceof Map) {       this.objectWrapper = new MapWrapper(this, (Map) object);     } else if (object instanceof Collection) {       this.objectWrapper = new CollectionWrapper(this, (Collection) object);     } else {       this.objectWrapper = new BeanWrapper(this, object);     }   } 

简单解释下传递进来的参数,第一个 object 就是我们在进行执行 sql 的时候传递进来的参数类型,有几种情况,一种的 map,一种是实体 bean,或者是 Collection 等。

里面有一个参数是 ObjectWrapper ,在构造方法当中会判断 object 的类型来创建 ObjectWrapper 的实例。

继续来看 ParameterMappingTokenHandler.buildParameterMapping 方法当中,有一段代码是:

String property = propertiesMap.get("property"); Class<?> propertyType; if (metaParameters.hasGetter(property))  //通过 property 来获取 property 的类型,property 可以是 OGNL 表达式的字符串,例如: // user.address.name 、 user[addressStr] 这样的 

来看 MetaObject 的 hasGetter 方法:

public boolean hasGetter(String name) {     return objectWrapper.hasGetter(name);   }  //假设我们传递进来的是参数是实体 bean,那么 objectWrapper 就是 BeanWrapper 对象 //BeanWrapper 当中的 hasGetter 方法 public boolean hasGetter(String name) {     PropertyTokenizer prop = new PropertyTokenizer(name);     if (prop.hasNext()) {       if (metaClass.hasGetter(prop.getIndexedName())) {         MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());         if (metaValue == SystemMetaObject.NULL_META_OBJECT) {           return metaClass.hasGetter(name);         } else {           return metaValue.hasGetter(prop.getChildren());         }       } else {         return false;       }     } else {       return metaClass.hasGetter(name);     }   } 

先来看下 BeanWrapper 的构造方法:

public class BeanWrapper extends BaseWrapper {    private Object object;   private MetaClass metaClass;    public BeanWrapper(MetaObject metaObject, Object object) {     super(metaObject);     this.object = object;     this.metaClass = MetaClass.forClass(object.getClass(), metaObject.getReflectorFactory());   } } 

MetaClass 先不分析,后续进行分析。

在看 BeanWrapper.hasGetter 方法,第一行就是创建 PropertyTokenizer 对象。

简单描述下 PropertyTokenizer 类就是用来解析 OGNL 表达式的情况的。

public class PropertyTokenizer implements Iterable<PropertyTokenizer>, Iterator<PropertyTokenizer> {   private String name;   private String indexedName;   private String index;   private String children;    public PropertyTokenizer(String fullname) {     int delim = fullname.indexOf('.');     if (delim > -1) {       name = fullname.substring(0, delim);       children = fullname.substring(delim + 1);     } else {       name = fullname;       children = null;     }     indexedName = name;     delim = name.indexOf('[');     if (delim > -1) {       index = name.substring(delim + 1, name.length() - 1);       name = name.substring(0, delim);     }   } 

以两个例子来看下构造方法初始化的过程:

//参数 user.address.name //结果 name = user,children = address.name,indexedName = user,index = null  //参数 user[addressStr] //结果 name = user,children = null,indexedName = user[addressStr],index = addressStr 

继续看 BeanWrapper.hasGetter 方法,下面的调用过程:

public boolean hasGetter(String name) {  PropertyTokenizer prop = new PropertyTokenizer(name);     if (prop.hasNext()) {       if (metaClass.hasGetter(prop.getIndexedName())) {         MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());         if (metaValue == SystemMetaObject.NULL_META_OBJECT) {           return metaClass.hasGetter(name);         } else {           return metaValue.hasGetter(prop.getChildren());         }       } else {         return false;       }     } else {       return metaClass.hasGetter(name);     } }  //PropertyTokenizer 当中的方法 @Override   public boolean hasNext() {     return children != null;   } 

根据第一个例子的情况,参数 user.address.name, hasNext() 返回 true,因为 children = address.name,所以进入 if 语句后又会执行:

if (metaClass.hasGetter(prop.getIndexedName()))  //PropertyTokenizer 当中的方法 public String getIndexedName() {     return indexedName;//参数是 user.address.name 的时候 indexedName = user   }  //MetaClass 当中的方法 public boolean hasGetter(String name) {//此时 name 的值是 user     PropertyTokenizer prop = new PropertyTokenizer(name);     if (prop.hasNext()) {//此时返回的是 false       if (reflector.hasGetter(prop.getName())) {         MetaClass metaProp = metaClassForProperty(prop);         return metaProp.hasGetter(prop.getChildren());       } else {         return false;       }     } else {       return reflector.hasGetter(prop.getName());//反射获取对应的 user 对象     }   } 

然后继续执行:

MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());         if (metaValue == SystemMetaObject.NULL_META_OBJECT) {           return metaClass.hasGetter(name);         } else {           return metaValue.hasGetter(prop.getChildren());         } 

执行过程不深入跟踪,就是获取到 user 的对象,然后在包装成 MetaObject 对象,然后继续调用 hasGetter 方法,并且传递进去 childeren 就是 address.name 参数,递归形式的进行解析。

所以在 ParameterMappingTokenHandler 当中的 buildParameterMapping 方法里面就这样获取到了 propertyType 的类型。

MetaClass

在 BeanWrapper 当中有个属性是 MetaClass 的对象,我们来分析下 MetaClass。

在 BeanWrapper 的构造方法当中如下创建 MetaClass 实例:

this.metaClass = MetaClass.forClass(object.getClass(), metaObject.getReflectorFactory());  public class MetaClass {   private ReflectorFactory reflectorFactory;   private Reflector reflector;    private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) {  this.reflectorFactory = reflectorFactory;     this.reflector = reflectorFactory.findForClass(type);   } public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) {     return new MetaClass(type, reflectorFactory);   } 

metaObject 当中的 getReflectorFactory 就是 Configuration 当中的 reflectorFactory,来看下 ReflectorFactory 接口的内容,以及默认实现:

public interface ReflectorFactory {    boolean isClassCacheEnabled();//是否 Class 可以缓存    void setClassCacheEnabled(boolean classCacheEnabled);//设置 Class 是否可以缓存    Reflector findForClass(Class<?> type);// 根据 Class 查找 Reflector }  public class DefaultReflectorFactory implements ReflectorFactory {   private boolean classCacheEnabled = true;   private final ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<Class<?>, Reflector>();    public DefaultReflectorFactory() {   }    @Override   public boolean isClassCacheEnabled() {     return classCacheEnabled;   }    @Override   public void setClassCacheEnabled(boolean classCacheEnabled) {     this.classCacheEnabled = classCacheEnabled;   }    @Override   public Reflector findForClass(Class<?> type) {     if (classCacheEnabled) {             // synchronized (type) removed see issue #461       Reflector cached = reflectorMap.get(type);       if (cached == null) {         cached = new Reflector(type);         reflectorMap.put(type, cached);       }       return cached;     } else {       return new Reflector(type);     }   }  } 

默认实现也比较简单,就是里面添加了个 ConcurrentMap ,不多解释。

MetaClass 里面还有一个属性是 Reflector,这个也是 ReflectorFactory 获取的类型。

public class Reflector {    private static final String[] EMPTY_STRING_ARRAY = new String[0];    private Class<?> type;   private String[] readablePropertyNames = EMPTY_STRING_ARRAY;   private String[] writeablePropertyNames = EMPTY_STRING_ARRAY;   private Map<String, Invoker> setMethods = new HashMap<String, Invoker>();   private Map<String, Invoker> getMethods = new HashMap<String, Invoker>();   private Map<String, Class<?>> setTypes = new HashMap<String, Class<?>>();   private Map<String, Class<?>> getTypes = new HashMap<String, Class<?>>();   private Constructor<?> defaultConstructor;    private Map<String, String> caseInsensitivePropertyMap = new HashMap<String, String>();   public Reflector(Class<?> clazz) {     type = clazz;     addDefaultConstructor(clazz);//添加默认的无参数的构造方法     addGetMethods(clazz);//所有 get 方法添加到 map     addSetMethods(clazz);//所有 set 方法添加到 map     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);     }   }   // 省略代码..  } 

从属性以及构造方法当中调用的一些方法可以看出来了,这个类就是用来简化反射操作的一个工具类。不仔细研究了。

下篇继续分析 mybatis 的其他内容。

—EOF—

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » mybatis 源码分析之 ObjectFactory 等

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮