mybatis源碼解析-getMapper

之前兩篇文章:
mybatis源碼解析-SqlsessionFactory
mybatis源碼解析-獲取Sqlsession
介紹了在mybatis運行中的前兩步的執行過程和原理,繼續擺出我們的demo:

//1.通過輸入流解析xml配置文件
InputStream inputstream = Resources.getResourceAsStream("xxx.xml")
SqlsessionFactory sqlsessionfactory = new SqlsessionFactoryBuilder().build(inputstream);
//2.獲取和數據庫的鏈接,創建會話
SqlSession openSession = sqlsessionfactory.openSession();
//3.獲取接口的實現類對象,會爲接口自動的創建一個代理對象mapper,代理對象會去執行增刪改查方法
xxxMapper mapper = openSession.getMapper(xxxMapper.class)
//4.執行增刪改的方法

接下來我們聊聊openSession.getMapper(xxxMapper.class)這一步,前面說了,sqlsessionfactory.openSession();返回一個默認的DefaultSqlSessionSqlSession對象,這個對象裏面包含Executor和Configuration

getMapper

1.1:直接進入getMapper方法:

public <T> T getMapper(Class<T> type) {
        return this.configuration.getMapper(type, this);
    }

它是調用configuration的getMapper方法:
在這裏插入圖片描述
在我們之前的介紹中提到過,Configuration是全局配置對象,裏面保存了所有配置文件信息以及兩個很重要的屬性分別如下:
在這裏插入圖片描述
1.2我們進入mapperRegistry.getMapper方法

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
        if (mapperProxyFactory == null) {
            throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
        } else {
            try {
                return mapperProxyFactory.newInstance(sqlSession);
            } catch (Exception var5) {
                throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
            }
        }
    }

代碼中寫的很明確了,根據接口類型獲取MapperProxyFactory,拿到該對象後執行mapperProxyFactory.newInstance(sqlSession);這個方法,我們進入該方法:
1.3

protected T newInstance(MapperProxy<T> mapperProxy) {
        return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
    }

    public T newInstance(SqlSession sqlSession) {
        MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
        return this.newInstance(mapperProxy);
    }

我們進入了該方法,發現MapperProxy<T>,繼續點進去:
在這裏插入圖片描述
這個類中有SqlSession,對應接口類型Class<T> mapperInterface,以及方法映射Map<Method, MapperMethod> methodCache,並且該類實現了InvocationHandler,然後調用

protected T newInstance(MapperProxy<T> mapperProxy) {
        return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
    }

這個方法,這個方法裏用的是反射包下的Proxy對象創建mapperProxy,然後一步步返回
xxxMapper mapper = openSession.getMapper(xxxMapper.class)
最終返回的是代理對象,這個mapper裏面封裝了sqlsession對象,而sqlsession裏面創建了Executor來執行sql語句,因此可以使用這個mapper代理類來實現具體的增刪改查操作了

總結:

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章