1、获取创建SqlSession的工厂类SqlSessionFactory
自动装配类MybatisAutoConfiguration
的作用:
- 利用
DataSourceAutoConfiguration
引入合适的dataSource。 - 借助
SqlSessionFactoryBean
创建SqlSession的工厂类之DefaultSqlSessionFactory
。 - 创建
SqlSessionTemplate
,其中该模板类是对SqlSession做jdk代理。
DefaultSqlSessionFactory实例化之前SqlSessionFactoryBean内部优先实例化Configuration
、解析自定义的xml文件等,如下所示:
public class SqlSessionFactoryBean{
private Resource[] mapperLocations;
private DataSource dataSource;
private Configuration configuration;
protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
final Configuration targetConfiguration = new Configuration();
...
Stream.of(this.plugins).forEach(plugin -> {targetConfiguration.addInterceptor(plugin);});
...
SpringManagedTransactionFactory smtf = new SpringManagedTransactionFactory();
Environment e = new Environment(environment,transactionFactory == null ? smtf : transactionFactory,dataSource)
targetConfiguration.setEnvironment(e);
InputStream is = mapperLocation.getInputStream();
Map<String, XNode> sqlFragments= targetConfiguration.getSqlFragments();
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(is,targetConfiguration, mapperLocation,sqlFragments);
xmlMapperBuilder.parse();
return new DefaultSqlSessionFactory(targetConfiguration);
}
}
public class SqlSessionTemplate implements SqlSession, DisposableBean {
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
PersistenceExceptionTranslator exceptionTranslator) {
...
// 对DefaultSqlSession的代理
this.sqlSessionProxy = (SqlSession) newProxyInstance(cl,new Class[] { SqlSession.class }, si);
}
@Override
public <T> T getMapper(Class<T> type) {
//从SqlSessionFactory工厂类中获取Configuration
return getConfiguration().getMapper(type, this);
}
}
2、Mapper类型的接口实例化
@MapperScan
引入ImportBeanDefinitionRegistrar类型的MapperScannerRegistrar,这也是Spring在解析@Import注解时涉及的一种类型。
public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
String className = MapperScan.class.getName()
Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(className);
AnnotationAttributes mapperScanAttrs = AnnotationAttributes.fromMap(annotationAttributes);
if (mapperScanAttrs != null) {
registerBeanDefinitions(mapperScanAttrs, registry, generateBaseBeanName(importingClassMetadata, 0));
}
}
void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry, String beanName) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
...//解析@MapperScan相关属性,并赋值给MapperScannerConfigurer中相关属性
List<String> basePackages = new ArrayList<>();
basePackages.addAll(Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText)
.collect(Collectors.toList()));
builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(basePackages));
registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
}
}
引入的核心类MapperScannerConfigurer
是BeanDefinitionRegistryPostProcessor
类型的后置处理器。在此后置处理器内部会扫描@MapperScan配置路径下全部的Mapper接口。每个接口对应BeanDefinitionHolder其class类型均为MapperFactoryBean
。
2.1.创建Mapper接口的BeanDefinition
扫描@MapperScan所指定路径下所有的mapper接口,为每个接口创建其对应的BeanDefinition,其中Class属性为 MapperFactoryBean
。
MapperFactoryBean的抽象类SqlSessionDaoSupport
存在类型为SqlSessionTemplate的属性,所以在每个BeanDefinition中都会指定SqlSessionTemplate赋值的方式。
如果没有注解@MapperScan显式指定SqlSessionTemplate的bean Name,默认情况选择AbstractBeanDefinition.AUTOWIRE_BY_TYPE
方式属性赋值。
public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean{
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.setAddToConfig(this.addToConfig);
...
String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, CONFIG_LOCATION_DELIMITERS));
}
}
public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {
private Class<? extends MapperFactoryBean> mapperFactoryBeanClass = MapperFactoryBean.class;
@Override
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
// 扫描@MapperScan指定路径下的mapper接口
Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
if (beanDefinitions.isEmpty()) {
} else {
// 设置目标扫描bean对应Class属性为 MapperFactoryBean
processBeanDefinitions(beanDefinitions);
}
return beanDefinitions;
}
private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
GenericBeanDefinition definition;
for (BeanDefinitionHolder holder : beanDefinitions) {
definition = (GenericBeanDefinition) holder.getBeanDefinition();
...
definition.setBeanClass(this.mapperFactoryBeanClass);
definition.getPropertyValues().add("addToConfig", this.addToConfig);
boolean explicitFactoryUsed = false;
//如果@MapperScan指定了 sqlSessionFactoryRef
if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {
RuntimeBeanReference r = new RuntimeBeanReference(this.sqlSessionFactoryBeanName);
definition.getPropertyValues().add("sqlSessionFactory",r);
explicitFactoryUsed = true;
} else if (this.sqlSessionFactory != null) {
definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);
explicitFactoryUsed = true;
}
//如果@MapperScan指定了 sqlSessionTemplateBeanName
if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
RuntimeBeanReference r = new RuntimeBeanReference(this.sqlSessionTemplateBeanName);
definition.getPropertyValues().add("sqlSessionTemplate",r);
explicitFactoryUsed = true;
} else if (this.sqlSessionTemplate != null) {
definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);
explicitFactoryUsed = true;
}
//如果@MapperScan没有指定sqlSessionTemplateBeanName,则利用@Autowired功能注入
if (!explicitFactoryUsed) {
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
}
}
}
}
3、每个Mapper接口生成代理
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
@Override
public T getObject() throws Exception {
// 从父类SqlSessionDaoSupport中获取SqlSession之SqlSessionTemplate
return getSqlSession().getMapper(this.mapperInterface);
}
}
最终利用工厂类MapperProxyFactory完成对目标接口的JDK代理。
public class MapperProxyFactory<T> {
protected T newInstance(MapperProxy<T> mapperProxy) {
ClassLoader cl = mapperInterface.getClassLoader();
return (T) Proxy.newProxyInstance(cl, new Class[] { mapperInterface }, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
// MapperProxy类型为InvocationHandler
//sqlSession即为SqlSessionDaoSupport中属性SqlSessionTemplate
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
}
至此,@MapperScan指定路径下的所有mapper接口在Spring IOC容器中都生成了class类型为MapperFactoryBean的代理bean。
4、代理目标接口中的目标方法
public class MapperProxy<T> implements InvocationHandler {
// SqlSessionDaoSupport中属性SqlSessionTemplate
private final SqlSession sqlSession;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
...
final MapperMethod mapperMethod = cachedMapperMethod(method);
return mapperMethod.execute(sqlSession, args);
}
}
3、SqlSession
- 针对Springboot中,其子类包括SqlSessionTemplate、DefaultSqlSession。
- 持有增删改查等基本api。以及辅助API「提交、关闭会话」。
- 每个SQL请求都会创建一个SqlSession会话处理。
3.1、DefaultSqlSessionFactory
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
final Environment environment = configuration.getEnvironment();
//transactionFactory:SpringManagedTransactionFactory
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
// tx = SpringManagedTransaction,并持有 DataSource
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
// # 4.1
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
}
3.2、DefaultSqlSession
public class DefaultSqlSession implements SqlSession {
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
this.configuration = configuration;
this.executor = executor;
this.dirty = false;
this.autoCommit = autoCommit;
}
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
MappedStatement ms = configuration.getMappedStatement(statement);
// #5.1:CacheExecutor#query
return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
}
}
4、Configuration
4.1、创建Executor
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
// transaction:SpringManagedTransaction
// this:Configuration
// #5.2
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) {//默认为true
// #5.1:CachingExecutor 持有真正执行SQL功能的SimpleExecutor
executor = new CachingExecutor(executor);
}
// #9 【初始化 Executor 相关的拦截器插件】
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
5、Executor
5.1、CacheExecutor
// delegate:SimpleExecutor
public CachingExecutor(Executor delegate) {
this.delegate = delegate;
delegate.setExecutorWrapper(this);
}
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
BoundSql boundSql = ms.getBoundSql(parameterObject);
// 二级缓存key
CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)throws SQLException {
Cache cache = ms.getCache();
if (cache != null) {
flushCacheIfRequired(ms);
if (ms.isUseCache() && resultHandler == null) {
ensureNoOutParams(ms, boundSql);
@SuppressWarnings("unchecked")
List<E> list = (List<E>) tcm.getObject(cache, key);
if (list == null) {
list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
tcm.putObject(cache, key, list); // issue #578 and #116
}
return list;
}
}
//delegate 表示SimpleExecutor。SimpleExecutor是真正执行SQL功能,其对应的方法为doQuery或者doUpdate...
//此处利用 模版 方式,调用的是抽象类BaseExecutor#query方法「BaseExecutor主要是处理一级缓存」
return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
5.2、SimpleExecutor
public SimpleExecutor(Configuration configuration, Transaction transaction) {
// #5.3
super(configuration, transaction);
}
5.2.1、初始化Connection
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler,
BoundSql boundSql) throws SQLException {
Configuration configuration = ms.getConfiguration();
// #8.1 RoutingStatementHandler
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler,
boundSql);
stmt = prepareStatement(handler, ms.getStatementLog());
// RoutingStatementHandler#query
return handler.query(stmt, resultHandler);
}
//handler:RoutingStatementHandler
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Statement stmt;
// #7 通过 SpringManagedTransaction 获取 连接对象Connection
Connection connection = getConnection(statementLog);
// 如果 存在StatementHandler的插件,则调用 handler 为代理对象,直接调用 9.3、Plugin#invoke 【最终调用 PageInterceptors#intercept】,其中以 PageInterceptors 为例。
// 执行 PageInterceptors#intercept 方法之后,最终执行到 #8.1 RoutingStatementHandler#prepare
stmt = handler.prepare(connection, transaction.getTimeout());
handler.parameterize(stmt);
return stmt;
}
5.3、BaseExecutor
//transaction:SpringManagedTransaction
protected BaseExecutor(Configuration configuration, Transaction transaction) {
this.transaction = transaction;
this.configuration = configuration;
}
5.3.1、处理一级缓存localCache
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
...
List<E> list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
...
return list;
}
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
List<E> list;
localCache.putObject(key, EXECUTION_PLACEHOLDER);
try {
//#5.2~doQuery
list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
} finally {
localCache.removeObject(key);
}
localCache.putObject(key, list);
...
return list;
}
6、 MappedStatement
public final class MappedStatement{
private Configuration configuration;
//net.ss.mapper.CommentDAO.query || net.ss.mapper.CommentDAO.save等
private String id;
private StatementType statementType;
private ResultSetType resultSetType;
private SqlSource sqlSource;
private Cache cache;
private ParameterMap parameterMap;
private List<ResultMap> resultMaps;
}
基于 groovy + 注解方式分析。启动过程中处理所有的接口dao层。
public class Configuration {
// type:表示dao层的接口,net.ss.mapper.CommentDAO
public <T> void addMapper(Class<T> type) {
mapperRegistry.addMapper(type);
}
public <T> void addMapper(Class<T> type) {
...
knownMappers.put(type, new MapperProxyFactory<>(type));//用于dao层接口实现动态代理
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
parser.parse();
...
}
}
public class MapperAnnotationBuilder{
public void parse() {
Method[] methods = type.getMethods();
for (Method method : methods) {
parseStatement(method);
}
}
void parseStatement(Method method) {
...
SqlSource sqlSource = getSqlSourceFromAnnotations(method, parameterTypeClass, languageDriver);
//初始化 MappedStatement
assistant.addMappedStatement(...)
}
}
public class MapperBuilderAssistant extends BaseBuilder {
public MappedStatement addMappedStatement(...){
...
MappedStatement statement = statementBuilder.build();
// 由Configuration属性「Map<String, MappedStatement> mappedStatements」持有所有的MappedStatement
configuration.addMappedStatement(statement);
}
}
6.1、SqlSource
BoundSql getBoundSql(Object parameterObject);
6.2、BoundSql
public class BoundSql {
private final String sql;
private final List<ParameterMapping> parameterMappings;
private final Object parameterObject;
private final Map<String, Object> additionalParameters;
private final MetaObject metaParameters;
public BoundSql(Configuration configuration, String sql, List<ParameterMapping> parameterMappings, Object
parameterObject) {
this.sql = sql;
this.parameterMappings = parameterMappings;
this.parameterObject = parameterObject;
this.additionalParameters = new HashMap<>();
this.metaParameters = configuration.newMetaObject(additionalParameters);
}
}
7、Connection
public abstract class BaseExecutor implements Executor{
// 通过 SpringManagedTransaction 获取 连接Connection
protected Connection getConnection(Log statementLog) throws SQLException {
Connection connection = transaction.getConnection();
if (statementLog.isDebugEnabled()) {
return ConnectionLogger.newInstance(connection, statementLog, queryStack);
} else {
return connection;
}
}
}
public class SpringManagedTransaction implements Transaction {
private void openConnection() throws SQLException {
// dataSource:HikariDataSource
this.connection = DataSourceUtils.getConnection(this.dataSource);
this.autoCommit = this.connection.getAutoCommit();
}
}
8、StatementHandler
8.1、RoutingStatementHandler
public class Configuration {
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object
parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject,
rowBounds, resultHandler, boundSql);
// #9:【初始化 StatementHandler的拦截器插件】
statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
return statementHandler;
}
}
RoutingStatementHandler
中代理的类都是继承至抽象类BaseStatementHandler
的实现类。
public class RoutingStatementHandler implements StatementHandler {
private final StatementHandler delegate;
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
ResultHandler resultHandler, BoundSql boundSql) {
switch (ms.getStatementType()) {
case STATEMENT:
delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case PREPARED:
delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case CALLABLE:
delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
}
}
@Override
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
// delegate:PreparedStatementHandler,根据模板模式,最终调用BaseStatementHandler#prepare
return delegate.prepare(connection, transactionTimeout);
}
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
//delegate:PreparedStatementHandler
return delegate.query(statement, resultHandler);
}
}
public abstract class BaseStatementHandler implements StatementHandler {
protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject,
RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
this.configuration = mappedStatement.getConfiguration();
this.executor = executor;
this.mappedStatement = mappedStatement;
this.rowBounds = rowBounds;
this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
this.objectFactory = configuration.getObjectFactory();
if (boundSql == null) { // issue #435, get the key before calculating the statement
generateKeys(parameterObject);
boundSql = mappedStatement.getBoundSql(parameterObject);
}
this.boundSql = boundSql;
// 初始化 ParameterHandler
this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
//初始化 ResultSetHandler
this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler,
resultHandler, boundSql);
}
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
ErrorContext.instance().sql(boundSql.getSql());
Statement statement = null;
try {
// 根据connection获取 HikariProxyPreparedStatement
statement = instantiateStatement(connection);
setStatementTimeout(statement, transactionTimeout);
setFetchSize(statement);
return statement;
}
}
}
8.2、ParameterHandler
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql{
// DefaultParameterHandler
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement,
parameterObject, boundSql);
// #9:【初始化 ParameterHandler的拦截器插件】
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
return parameterHandler;
}
8.3、ResultSetHandler
public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds,
ParameterHandler parameterHandler,ResultHandler resultHandler, BoundSql boundSql) {
// DefaultResultSetHandler
ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
// #9:【初始化 ResultSetHandler的拦截器插件】
resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
return resultSetHandler;
}
8.4、PreparedStatementHandler
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
// 最终执行原生jdbc对数据的操作
ps.execute();
//处理结果映射
return resultSetHandler.handleResultSets(ps);
}
9、拦截器拦截插件
9.1、InterceptorChain
public class InterceptorChain {
//用户自定义的所有拦截器插件
private final List<Interceptor> interceptors = new ArrayList<>();
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
}
9.2、PageInterceptors
以分页插件 PageInterceptors 为示例:
@Override
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
9.3、Plugin
public class Plugin implements InvocationHandler {
private final Object target;
private final Interceptor interceptor;
private final Map<Class<?>, Set<Method>> signatureMap;
private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) {
this.target = target;
this.interceptor = interceptor;
this.signatureMap = signatureMap;
}
// target:拦截器插件类型,interceptor:自定义拦截器【PageInterceptors】
public static Object wrap(Object target, Interceptor interceptor) {
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
Class<?> type = target.getClass();
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
if (interfaces.length > 0) {//如果当前type实现了拦截器,则通过jdk接口代理生成当前 type 的代理类
return Proxy.newProxyInstance(
type.getClassLoader(),
interfaces,
new Plugin(target, interceptor, signatureMap));
}
return target;
}
// 执行完
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Set<Method> methods = signatureMap.get(method.getDeclaringClass());
if (methods != null && methods.contains(method)) {
// interceptor 为自定义的 【PageInterceptors】
return interceptor.intercept(new Invocation(target, method, args));
}
return method.invoke(target, args);
} catch (Exception e) {
throw ExceptionUtil.unwrapThrowable(e);
}
}
// 具体解析 某个拦截器
private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) {
// 获取 注解@Intercepts的内容
Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
...
// 获取 注解@Intercepts中@Signature注解的 所有value属性
Signature[] sigs = interceptsAnnotation.value();
Map<Class<?>, Set<Method>> signatureMap = new HashMap<>();
for (Signature sig : sigs) {
//通过 @Signature 注解中配置的 method & args 确定当前type 下的具体的方法
Set<Method> methods = signatureMap.computeIfAbsent(sig.type(), k -> new HashSet<>());
Method method = sig.type().getMethod(sig.method(), sig.args());
methods.add(method);
}
return signatureMap;
}
private static Class<?>[] getAllInterfaces(Class<?> type, Map<Class<?>, Set<Method>> signatureMap) {
Set<Class<?>> interfaces = new HashSet<>();
while (type != null) {
// 获取当前 type 下所有的接口
for (Class<?> c : type.getInterfaces()) {
// 实现插件拦截器的intercept,并非是当前type
if (signatureMap.containsKey(c)) {
interfaces.add(c);
}
}
type = type.getSuperclass();
}
return interfaces.toArray(new Class<?>[interfaces.size()]);
}
}
SqlSession & Executor区别
- CacheExecutor:处理二级缓存。
- 抽象类BaseExecutor:负责处理基本功能&一级缓存。query & update 方法。
- SimpleExecutor真正执行SQL功能。doQuery & doUpdate 方法。