全网营销型网站建设,如何做链接淘宝客的网站,网站建设合同 简单,站长工具 seo查询在后续分析Mybatis 流程中代码的可能会用到IDEA debug 技巧#xff1a;
条件断点 代码断点#xff0c;右键 勾选弹窗 Condition #xff1a; 写入表达式 回到上一步#xff1a; Java动态代理实现 InvocationHandler接口#xff1a;
package com.lvyuanj.core.test;…在后续分析Mybatis 流程中代码的可能会用到IDEA debug 技巧
条件断点 代码断点右键 勾选弹窗 Condition 写入表达式 回到上一步 Java动态代理实现 InvocationHandler接口
package com.lvyuanj.core.test;import com.lvyuanj.core.model.User;
import org.apache.ibatis.annotations.Select;import java.util.List;public interface UserTestMapper {Select(select * from t_user)public ListUser query();
}
package com.lvyuanj.core.test;import org.apache.ibatis.annotations.Select;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(query db: method.getAnnotation(Select.class).value()[0]);return null;}}package com.lvyuanj.core.test;import java.lang.reflect.Proxy;public class MyQueryTest {public static void main(String[] args) {Class[] clazz {UserTestMapper.class};UserTestMapper userTestMapper (UserTestMapper) Proxy.newProxyInstance(MyQueryTest.class.getClassLoader(), clazz, new MyInvocationHandler());userTestMapper.query();}
}
mybatis 核心FactoryBean
MapperScannerRegistrar 实现了ImportBeanDefinitionRegistrar 接口。 可以自动注入
MapperScannerConfigurer 实现 BeanDefinitionRegistryPostProcessor这个类 postProcessBeanDefinitionRegistry中扫描注入mapper
MapperFactoryBean 实现了FactoryBean 也继承了SqlSessionDaoSupport 类
Spring 管理MapperFactoryBean 的时候设置属性的时候初始化SqlSessionTemplate
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {if (this.sqlSessionTemplate null || sqlSessionFactory ! this.sqlSessionTemplate.getSqlSessionFactory()) {this.sqlSessionTemplate createSqlSessionTemplate(sqlSessionFactory);}}需要的SqlSessionFactory 在AppConfig中定义由于SqlSessionFactoryBean实现FactoryBean接口类factoryBean.getObject(); 获取到真实的对象SqlSessionFactory
在创建对象的时候时候进行afterPropertiesSet(); 对象 public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);}Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {SqlSessionFactoryBean factoryBean new SqlSessionFactoryBean();factoryBean.setDataSource(dataSource());return factoryBean.getObject();
}当开发者调用userMapper.selectAll() 方法的时候由于userMapper是MapperFactoryBean 工厂bean创建的Bean的时候调用的是MapperFactoryBean.getObject(); 最终调用org.apache.ibatis.binding.MapperRegistry#getMapper(Class type, SqlSession sqlSession) 方法中调用 mapperProxyFactory.newInstance(sqlSession)
Overridepublic T getObject() throws Exception {return getSqlSession().getMapper(this.mapperInterface);}public T T getMapper(ClassT type, SqlSession sqlSession) {final MapperProxyFactoryT mapperProxyFactory (MapperProxyFactoryT) knownMappers.get(type);if (mapperProxyFactory null) {throw new BindingException(Type type is not known to the MapperRegistry.);}try {return mapperProxyFactory.newInstance(sqlSession);} catch (Exception e) {throw new BindingException(Error getting mapper instance. Cause: e, e);}}protected T newInstance(MapperProxyT mapperProxy) {return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);}public T newInstance(SqlSession sqlSession) {final MapperProxyT mapperProxy new MapperProxyT(sqlSession, mapperInterface, methodCache);return newInstance(mapperProxy);}SqlSessionTemplate 是SqlSession 的实现类
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,PersistenceExceptionTranslator exceptionTranslator) {notNull(sqlSessionFactory, Property sqlSessionFactory is required);notNull(executorType, Property executorType is required);this.sqlSessionFactory sqlSessionFactory;this.executorType executorType;this.exceptionTranslator exceptionTranslator;this.sqlSessionProxy (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),new Class[] { SqlSession.class }, new SqlSessionInterceptor());}Overridepublic T T selectOne(String statement, Object parameter) {return this.sqlSessionProxy.selectOne(statement, parameter);}/*** {inheritDoc}*/Overridepublic K, V MapK, V selectMap(String statement, String mapKey) {return this.sqlSessionProxy.selectMap(statement, mapKey);}/*** {inheritDoc}*/Overridepublic K, V MapK, V selectMap(String statement, Object parameter, String mapKey) {return this.sqlSessionProxy.selectMap(statement, parameter, mapKey);}......代理类
private class SqlSessionInterceptor implements InvocationHandler {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {SqlSession sqlSession getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);try {Object result method.invoke(sqlSession, args);if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) { //是否启用事务管理没有事务管理mybatis自己管理// force commit even on non-dirty sessions because some databases require// a commit/rollback before calling close()sqlSession.commit(true);}return result;} catch (Throwable t) {Throwable unwrapped unwrapThrowable(t);if (SqlSessionTemplate.this.exceptionTranslator ! null unwrapped instanceof PersistenceException) {// release the connection to avoid a deadlock if the translator is no loaded. See issue #22closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);sqlSession null;Throwable translated SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);if (translated ! null) {unwrapped translated;}}throw unwrapped;} finally {if (sqlSession ! null) {closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);}}}}开始涉及MyBatis SqlSession部分的一些机制关于MyBatis sqlSession的一点整理SqlSession主要是MyBatis定义的用于进行持久化操作的对象对connection进行了包装。在上面Spring Transaction的机制中我们获取到了connection之后会首先调用SqlSessionUtils里面的getSession方法判断当前的sqlSessionHolder以及是否存在事务锁定。
public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType,PersistenceExceptionTranslator exceptionTranslator) {notNull(sessionFactory, NO_SQL_SESSION_FACTORY_SPECIFIED);notNull(executorType, NO_EXECUTOR_TYPE_SPECIFIED);SqlSessionHolder holder (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);SqlSession session sessionHolder(executorType, holder);if (session ! null) {return session;}LOGGER.debug(() - Creating a new SqlSession);session sessionFactory.openSession(executorType);registerSessionHolder(sessionFactory, executorType, exceptionTranslator, session);return session;}sessionFactory.openSession(executorType); sessionFactory上文中在sqlSessionFactoryBean 实现InitializingBean接口初始化的时候afterPropertiesSet() 方法被调用 this.sqlSessionFactory buildSqlSessionFactory(); 执行是new DefaultSqlSessionFactory()对象。 Overridepublic SqlSession openSession(ExecutorType execType) {return openSessionFromDataSource(execType, null, false);}private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {Transaction tx null;try {final Environment environment configuration.getEnvironment();final TransactionFactory transactionFactory getTransactionFactoryFromEnvironment(environment);tx transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);final Executor executor configuration.newExecutor(tx, execType);return new DefaultSqlSession(configuration, executor, autoCommit);} catch (Exception e) {closeTransaction(tx); // may have fetched a connection so lets call close()throw ExceptionFactory.wrapException(Error opening session. Cause: e, e);} finally {ErrorContext.instance().reset();}}final TransactionFactory transactionFactory getTransactionFactoryFromEnvironment(environment); 获取事务工厂类第一次的时候new ManagedTransactionFactory(); tx transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); 创建一个事务对象 final Executor executor configuration.newExecutor(tx, execType);
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 {executor new SimpleExecutor(this, transaction);}if (cacheEnabled) {executor new CachingExecutor(executor);}executor (Executor) interceptorChain.pluginAll(executor);return executor;}UserMapper 初始化到调用链流程图