深入源码理解Spring整合MyBatis原理

聊一聊MyBatis的核心概念、Spring相关的核心内容,主要结合源码理解Spring是如何整合MyBatis的。(结合右侧目录了解吧)

MyBatis相关核心概念粗略回顾 SqlSessionFactory

创建SqlSession的工厂

SqlSession

sql请求的会话,通过SqlSessionFactory获取。

String resource = "mybatis-config.xml"; InputStream resourceAsStream = Resources.getResourceAsStream(resource); SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream); // 通过Builder获取构建SqlSessionFactory(读取mybatis-config.xml文件配置) SqlSession sqlSession = sqlSessionFactory.openSession(); // 开启Session UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.findByUserId(1);

上述代码就是单独使用MyBatis的时候的API例子。读取mybatis-config.xml构建出SqlSessionFactory,通过Factory开启SqlSession,使用SqlSession获取Mapper的代理实例。

Mapper public interface UserMapper { User findByUserId(Integer userId); } <mapper namepsace = "com.deepz.mybatis.user.UserMapper"> <select id = "findByUserId" resultType="User"> ... </select> </mapper>

以上就是咱们熟悉的MyBatis使用代码了,一个Mapper接口对应的就有一个XML文件。

Spring相关核心概念粗略回顾 FactoryBean接口

是一种特殊的SpringBean,对应的真实实例是FactoryBean接口中getObject()方法的返回值,用于自定义复杂的Bean生成。

FactoryBean类型的Bean的获取

AbstractBeanFactory#doGetBean

Object sharedInstance = getSingleton(beanName); // 从三级缓存中根据beanName获取SpringBean if (sharedInstance != null && args == null) { // 如果SpringBean不为空则说明命中缓存,直接获取SpringBean实例即可 if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); // 获取SpringBean真实实例(针对FactoryBean) }

AbstractBeanFactory#getObjectForBeanInstance

// Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { // 如果不是FactoryBean类型则直接返回 return beanInstance; } // 后续代码针对FactoryBean类型的SpringBean处理 Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); // 从缓存中获取 } if (object == null) { // Return bean instance from factory. FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); // 获取FactoryBean真实实例 } return object;

FactoryBeanRegistrySupport#doGetObjectFromFactoryBean
FactoryBeanRegistrySupport#getObjectFromFactoryBean最终会调到如下方法,通过FactoryBean的getObject()获取FactoryBean的真实实例

Object object; try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { return factory.getObject(); } }, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { object = factory.getObject(); // 显示调用FactoryBean#getObject } } InitializingBean接口

在SpringBean的生命周期中,Bean的初始化环节Spring会调用AbstractAutowireCapableBeanFactory#invokeInitMethods() 回调实现了InitializingBean接口的Bean的InitializingBean#afterPropertiesSet()

关于SpringBean生命周期欢迎移步笔者的相关总结随笔《深入源码理解SpringBean生命周期》

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); // Bean实现了InitializingBean接口 if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { ((InitializingBean) bean).afterPropertiesSet(); return null; } }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { ((InitializingBean) bean).afterPropertiesSet(); // 显式回调InitializingBean的afterPropertiesSet()方法 } } if (mbd != null) { String initMethodName = mbd.getInitMethodName(); if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); } } } BeanDefinitionRegistryPostProcessor接口

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzsjsw.html