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

1
2
3
4
5
6
7
<objectFactory type="">
<property name="" value=""/>
</objectFactory>

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

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

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

1
2
3
4
5
6
7
8
9
10
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 里面的属性,以及构造方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 方法当中,有一段代码是:

1
2
3
4
5
6
String property = propertiesMap.get("property");
Class<?> propertyType;
if (metaParameters.hasGetter(property))

//通过 property 来获取 property 的类型,property 可以是 OGNL 表达式的字符串,例如:
// user.address.name 、 user[addressStr] 这样的

来看 MetaObject 的 hasGetter 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 的构造方法:

1
2
3
4
5
6
7
8
9
10
11
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 表达式的情况的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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);
}
}

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

1
2
3
4
5
//参数 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 方法,下面的调用过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 语句后又会执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 对象
}
}

然后继续执行:

1
2
3
4
5
6
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 实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
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 接口的内容,以及默认实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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 获取的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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—