Spring 源码笔记-2.6 BeanWrapper 对比 MyBatis

# Spring vs MyBatis

Spring 和 MyBatis 中都有 BeanWrapper , Spring 中为接口, 实现类为 BeanWrapperImpl , 为了方便后面区分,本文用 SB 指代 Spring 的 BeanWrapperImpl ,用 MB 指代 MyBatis 中的 BeanWrapper。

# 功能

BeanWrapper 都属于各自框架的反射工具箱的重要组成部分。都是创建实例并且为其属性赋值的。以 SB 为例,下面的代码应该很容易看明白它的功能。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
BeanWrapper company = BeanWrapperImpl(new Company());
// setting the company name..
company.setPropertyValue("name", "Some Company Inc.");

// ... can also be done like this:
PropertyValue value = new PropertyValue("name", "Some Company Inc.");
company.setPropertyValue(value);

// ok, let's create the director and tie it to the company:
BeanWrapper jim = BeanWrapperImpl(new Employee());
jim.setPropertyValue("name", "Jim Stravinsky");
company.setPropertyValue("managingDirector", jim.getWrappedInstance());

// retrieving the salary of the managingDirector through the company
Float salary = (Float) company.getPropertyValue("managingDirector.salary");

# 共同点

  1. 核心功能功能基本相同
  2. 对要生成的类的要求规范也相同,有 get set 方法。
  3. 它们的底层也没有什么秘密,归根到底都是使用 java.lang.reflect 包下的 Constructor , Method 等等工具。

# 不同点

可能是我刚开始研究 SB 的原因,感觉 SB 源码更加复杂,结构也没那么清楚,关联了向下层级的工具类,很长很长一段的源码。 这篇博文 分析了其中一部分。

得益于已经学习过结构更为清晰的 MB,尽管 SB 源码复杂,但是读的时候不再会恐惧,因为简略的Debug 一遍就知道它底层还是调 getter/setter 的反射。再复杂的结构也离不开这最终的方法。

已目前对 SB 粗浅的了解来说,感受到最大的区别就是在工具箱中的结构地位不同

MB 属于BaseWrapper 的子类之一,同级别的还有 MapWrapper ,上级还有 CollectionWrapper 。

而 SB 就已经是在创建 Bean 时直接使用到的接口了。

解析嵌套参数名 (比如 user.name / address.city.mailcode),类型转换这些事情,SB 都能处理完。而 MB 都是先要使用其它工具类处理,比如依靠 PropertyTokenizer 。

总而言之,SB 就是对外的一个大接口,包含很多功能,MB 则是MyBatis 反射工具箱内的一个小的工具实现。