AOP在框架中的使用
简单记录一下见到过的AOP在框架中的使用记录,一直更新。
Bean声明周期中三级缓存时使用
spring事物上
自定义Aspectj切面
mybatis的mapper接口会生成代理对象
mybatis的plugin会生成代理对象
Mybatis的Mapper在注解扫描到实例化
MapperFactoryBean时在父类SqlSessionDaoSupport中初始化sqlSessionTemplate. 在SqlSessionTemplate构造方法中创建具体执行的sqlsession代理对象属性叫sqlSessionProxy.
/**
* 方法实现说明:真正会调该构造方法进行赋值初始化
*
* @author:xsls
* @param sqlSessionFactory:工厂对象
* @param executorType:执行器类型
* @param exceptionTranslator:异常翻译器对象(MyBatisExceptionTranslator)
* @return:
* @exception:
* @date:2019/9/8 19:49
*/
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;
/**
* sqlSession代理对象 来调用我们的目标方法
*/
this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),
new Class[] { SqlSession.class }, new SqlSessionInterceptor());
}
private class SqlSessionInterceptor implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* 尝试从事务的线程变量中获取session,若没有获取到就直接新开一个session, 所以加事务可以缓存我们的sqlSession(也就是我们的SqlSessionTemplate对象)
*/
SqlSession sqlSession = getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,
SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
try {
/**
* 调用我们的目标方法代理的就是我们的session接口的方法 因为上一步返回的session是我们DefaultSqlSession对象, 所以在这里直接调用到我们的DefaultSqlSession的方法中
*/
Object result = method.invoke(sqlSession, args);
if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
// force commit even on non-dirty sessions because some databases require
// a commit/rollback before calling close()
/**
* 提交我们的session
*/
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 #22
/**
* 抛异常 关闭我们的session
*/
closeSqlSession(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);
}
}
}
}
/**
* 方法实现说明:获取我们的session对象
*
* @author:xsls
* @param sessionFactory:session工厂对象
* @param executorType:执行器类型
* @param exceptionTranslator
* :异常分析器
* @exception:
* @date:2019/9/8 21:21
*/
public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType,
PersistenceExceptionTranslator exceptionTranslator) {
notNull(sessionFactory, NO_SQL_SESSION_FACTORY_SPECIFIED);
notNull(executorType, NO_EXECUTOR_TYPE_SPECIFIED);
/**
* 首先就去我们事务同步管理器对象中获取我们的sessionHolder
*/
SqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
/**
* 从事务管理器中获取我们的sqlSession对象
*/
SqlSession session = sessionHolder(executorType, holder);
// session不为空直接返回
if (session != null) {
return session;
}
LOGGER.debug(() -> "Creating a new SqlSession");
/**
* 新开一个session
*/
session = sessionFactory.openSession(executorType);
/**
* 把我们的session绑定到事务线程变量中
*/
registerSessionHolder(sessionFactory, executorType, exceptionTranslator, session);
return session;
}
本文链接:
/archives/1705924591505
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
刘同学的小站!
喜欢就支持一下吧