1、疑惑
看了一些中間件代碼,最大的疑惑是 mybatis 更像是一種工具一樣,并不是類似于 kafka 之類的 server、client 模式,它本身沒有看到任何的 main 方法,直接是拿來即用(當(dāng)然有一些流程順序),像是粘合劑,所以我一直以 server、client 模式理解它是不對的。
2、mapper 接口與映射文件綁定流程
以 mybatis 自身的 test 為例:

可以看到我們獲取 mapper 接口,執(zhí)行 mapper 中的方法之前,先進(jìn)行了配置文件的加載。而配置文件指明了我們要加載的 mapper.xml 文件是什么。

流程:
1.在這兩句話執(zhí)行的時候,特別是執(zhí)行到 build 方法時,mybatis 會先加載 mybatis-confg.xml 文件,然后在此配置文件中解析到對應(yīng)的 mapper.xml 文件。
Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/rounding/mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
根據(jù) mapper.xml 文件的內(nèi)容,解析其中的方法,將方法的全路徑名作為 key,某些一大坨作為 value(此 map 名為 mappedStatements,包括了原始 sql,但是此時參數(shù)未替換,執(zhí)行時候再替換),如下圖所示:

3、執(zhí)行 mapper 方法
SqlSession session = sqlSessionFactory.openSession();
Mapper mapper = session.getMapper(Mapper.class);
User user = mapper.getUser(1);
執(zhí)行 mapper 方法的時候,先根據(jù) mapper 接口名拿到對應(yīng)的代理類,然后調(diào)用代理類的方法進(jìn)行方法調(diào)用。

此時會從 mappedStatements 拿出對應(yīng)的方法,然后進(jìn)行參數(shù)替換,執(zhí)行使用數(shù)據(jù)庫連接執(zhí)行 sql。
4、感想
mybatis 大量運(yùn)用了 class(類的元信息)、method(方法的元信息)的各種方法,反正看了一圈之后,對動態(tài)代理更加熟悉了一丟丟。