<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<plugins>
<plugin interceptor="test.MybatisLogInterceptor"/>
</plugins>
.....
</configuration>
Mybatis를 사용하다가 Interceptor를 이용할일이 생겼다.
Interceptor를 등록을하고 사용을 하는데는 문제가 없었지만 어떠한 원리로 동작을 저렇게 할 수 있는지 궁금해졌다.
그래서 Mybatis를 뜯어보기로 결심했다. (Mybatis Source : github.com/mybatis/mybatis-3)
순서
1. SqlSessionFactoryBuilder.build |
2. XMLConfigBuilder.parse |
3. XMLConfigBuilder.parseConfiguration |
4. XMLConfigBuilder.pluginElement |
5. DefaultSqlSessionFactory.openSessionFromDataSource |
6. Configuration.newExecutor |
7. InterceptorChain.pluginAll |
8. Plugin.wrap |
하나하나 알아보도록 하겠다.
우리는 아래와같이 Configuration.xml 을 등록을 해놓고 reader를 통하여 파일을 읽을 것이다.
그리고나서 SqlSessionFactoryBuilder.build를 호출할때 파일의 정보를 같이 보내줄 것이다.
1. SqlSessionFactoryBuilder.build
SqlSessionFactoryBuilder의 build method를 보면 아래와같이 build할때 xml의 정보를 파싱하는 메소드를 호출한 후 파싱된 결과를 Configuration으로 등록하는 method를 호출한다.
2. XMLConfigBuilder.parse
parse method를 살펴보면 configuration 하위에있는 설정들을 읽어 Configuration 으로 등록하는 메소드를 호출한다.
3. XMLConfigBuilder.parseConfiguration
parseConfiguration method를 살펴보면 pluginElement라는 method가 존재한다.
해당 메소드는 plugin 설정을 읽어서 등록하는 method이다.
4. XMLConfigBuilder.pluginElement
pluginElement method를 보게 되면 interceptor로 지정되어있는 plugin을 읽어와 interceptor list에 추가한다.
이 interceptorList는 추후 Session을 open할때 중요한 역할을 하게된다.
Configuration을 보게되면 아래와같이 InterceptorChain 객체를 가진다.
InterceptorChain객체는 InterceptorList를 가진다.
5. DefaultSqlSessionFactory.openSessionFromDataSource
이전까지는 Configuration 등록의 문제였다면 이제부터는 Session을 open할때의 영역이다.
DefaultSqlSessionFactory.openSession 을 보게되면 openSessionFromDataSource method를 호출하게된다.
openSessionFromDataSource method는 설정된것을 토대로 Executor 객체를 생성한다.
6. Configuration.newExecutor
newExecutor method를 보게되면 executor 객체를 다 만들고 난뒤에 interceptorChain의 pluginAll 이라는 메소드를 실행하게 된다.
7. InterceptorChain.pluginAll
pluginAll메소드를 들어가게되면 4번 과정에서 등록됐던 Interceptor들의 plugin method를 호출한다.
현재 등록된 나의 Interceptor의 plugin method는 아래와 같다.
8. Plugin.wrap
Plugin.wrap 을 호출하게되면 interceptor가 있을 시 Proxy 객체를 반환한다.
여기서 PlugIn객체는 InvocationHandler를 구현한 객체이다.
Proxy 객체를 반환했으므로 사용자가 어떠한 Method를 호출하게되면 Plugin.invoke가 실행된다.
이것으로 Mybatis가 Interceptor를 어떻게 등록하고 어떻게 사용하는지(호출하는지) 알아보았습니다.
여기서 어떻게 invoke가 실행되는거야? 라는 생각이 드시는분들은 Proxy class를 공부하시면 좋을것 같습니다.
정확히는 Proxy.newProxyInstance 가 어떠한 방식으로 동작하는지 공부해보시면 좋을 것 같습니다.
혼자 공부하시기 힘들다면 인프런 - 더 자바, 코드를 조작하는 다양한 방법(백기선님)의 강좌를 보시면 도움이 될것 같습니다.
'개발 > JAVA' 카테고리의 다른 글
[Mybatis] Interface를 이용하여 Query 날리기 (0) | 2020.12.27 |
---|---|
[Mybatis] Application Server의 Connection Pool 이용하기 (0) | 2020.12.26 |
[JAVA] 함수의 결과를 성공과 실패만 판단하면 될때 반환값으로 어떤값이 좋을까? (2) | 2020.09.15 |
[JAVA] Stream을 이용하여 Map 안에 있는 값 간편하게 출력하기 (0) | 2020.08.23 |
[JAVA 8] Stream을 활용하여 합계를 구하는 여러가지 방법 (0) | 2020.08.21 |
댓글