面試官問,爲啥Mybatis的接口不須要實現類

爲啥Mybatis的接口不須要實現類

對啊,爲何不須要啊?
猜猜,多是動態代理生成了接口的對應的類
在這裏插入圖片描述
果真是動態生成的java

那是啥時候生成的呢

那就是我經過class獲取Mapper時生成的git

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

經過上面咱們一層層進入到下面的代碼github

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);// 1
    if (mapperProxyFactory == null) {
      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }
    try {
      return mapperProxyFactory.newInstance(sqlSession); // 2
    } catch (Exception e) {
      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }
  1. 獲取對應類型的MapperProxyFactory
  2. 建立MapperProxy,也就是咱們的UserMapper,咱們就能夠在其上調用咱們在接口中定義的方法了

具體是怎麼生成代理的呢?

public T newInstance(SqlSession sqlSession) {
    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy); // 1
  }
  1. 進入newInstance方法以下
protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

在這裏咱們又到了Proxy.newProxyInstance代碼,就是JDK建立代理的方法。面試

稍等,生成Proxy的MapperProxyFactory從而來

彆着急我尚未說完呢
knownMappers.get(type) 剛纔咱們經過這個獲取的MapperProxyFactory<T>,其中包含生成代理的接口集合mapperInterface
如今我說說,MapperProxyFactory從何而來,簡單說就是在解析XML時建立的
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
咱們一直進入到parseConfiguration方法,其中mapperElement(root.evalNode("mappers"));方法就是解析Mapper文件,註冊的MapperProxyFactoryMapperRegistry。一直跟蹤到下面的方法,在MapperRegistry中。sql

public <T> void addMapper(Class<T> type) {
  if (type.isInterface()) {
    if (hasMapper(type)) {
      throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
    }
    boolean loadCompleted = false;
    try {
      knownMappers.put(type, new MapperProxyFactory<>(type)); // 1
      MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
      parser.parse();
      loadCompleted = true;
    } finally {
      if (!loadCompleted) {
        knownMappers.remove(type);
      }
    }
  }
  1. 一直追蹤到knownMappers.put(type, new MapperProxyFactory<>(type));方法咱們找到了,在建立代理的時候,是用的是get方法,MapperProxyFactory就是從這添加的。

總結

今天咱們從爲Mapper接口建立代理對象開發,說到具體怎麼建立對象。mybatis

從初始化配置文件,建立MapperProxyFactory<T>,到當獲取Mapper,根據類型或者對應的MapperProxyFactory,使用JDK動態代理API建立代理對象。因而咱們就能夠調用法了。app

演示相關代碼源碼分析

歡迎討論學習學習

使用JDK API實現動態代理和源碼分析ui

Mybatis 插件和動態代理

面試官問,爲啥Mybatis的接口不須要實現類

面試官問,Mybatis插件加強邏輯的順序怎麼控制

相關文章
相關標籤/搜索