MyBatisPlus插件机制与执⾏流程原理分析
【1】MyBatis Plus插件
MyBatis Plus提供了分页插件PaginationInterceptor、执⾏分析插件SqlExplainInterceptor、性能分析插件PerformanceInterceptor
以及乐观锁插件OptimisticLockerInterceptor。
Mybatis 通过插件 (Interceptor) 可以做到拦截四⼤对象相关⽅法的执⾏ ,根据需求完成相关数据的动态改变。
四⼤对象是:
Executormysql语句的执行顺序
StatementHandler
ParameterHandler
ResultSetHandler
四⼤对象的每个对象在创建时,都会执⾏interceptorChain.pluginAll(),会经过每个插件对象的 plugin()⽅法,⽬的是为当前的四⼤对象
创建代理。代理对象就可以拦截到四⼤对象相关⽅法的执⾏,因为要执⾏四⼤对象的⽅法需要经过代理 。
① xml下插件的配置
如下所⽰:
<bean id="sqlSessionFactoryBean" class="batisplus.spring.MybatisSqlSessionFactoryBean"><!-- 数据源 --><property name="dataSource" ref="
② springboot下注册插件
这⾥以分页插件为例:
@Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); // 设置请求的页⾯⼤
③ SqlExplainInterceptor
SQL执⾏分析,全类名是batisplus.plugins.SqlExplainInterceptor,只⽀持 MySQL5.6.3以上版本。
该插件的作⽤是分析 DELETE UPDATE语句 ,防⽌⼩⽩或者恶意进⾏DELETE UPDATE全表操作,不建议在⽣产环境中使⽤会造成性能下
降,
在插件的底层通过SQL语句分析命令 Explain 分析当前的 SQL语句,根据结果集中的 Extra列来断定当前是否全表操作。
④性能分析插件
性能分析,全类名是batisplus.plugins.PerformanceInterceptor,⽤于输出每条 SQL 语句及其执⾏时间。
SQL性能执⾏分析 ,开发环境使⽤ 超过指定时间,停⽌运⾏。
⑤乐观锁插件
docker是什么型号全类名是batisplus.plugins.OptimisticLockerInterceptor。如果想实现如下需求 : 当要更新⼀条记录的时候,希望这
条记录没有被别⼈更新,就可以使⽤该插件进⾏判断。
乐观锁的实现原理(@Version ⽤于注解实体字段,必须要有) :
取出记录时,获取当前 version
更新时,带上这个version
执⾏更新时,set version = yourVersion+1 where version = yourVersion
如果 version不对,就更新失败
【2】获取sqlSessionFactoryBean
dev控件教程如下图所⽰,在系统启动时会初始化定义的bean。DefaultListableBeanFactory.preInstantiateSingletons⽅法中会从
beanDefinitionNames中获取bean name然后依次创建。
html中fixed是什么意思这⾥可以看到RootBeanDefinition是batisplus.spring.MybatisSqlSessionFactoryBean。
①获取bean的过程中bean属性
如下所⽰,在getBean过程中可以看到bean的属性:
② createBean
第⼀次获取bean的时候会⾛到ateBean进⾏bean的创建。
/** 创建⼀个bean实例,为bean实例设置属性值,调⽤post-processors-bean后置处理器 */@Overrideprotected Object createBean(String beanName, RootBeanDef //如果上⾯没有获取到bean,则会⾛doCreateBean--这也是创建bean的核⼼过程 Object beanInstance = doCreateBean(beanName, mbdToUse, args);//...暂时忽略
在solveBeforeInstantiation中就会分别执⾏bean后置处理器的前置和后置⽅法。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInsta
执⾏后置处理器的前置⽅法如下所⽰:
③ doCreateBean
AbstractAutowireCapableBeanFactory.doCreateBean是创建bean的核⼼⽅法,这会为bean属性赋值并会触发bean后置处理器、InitializingBean以及⾃定init⽅法等。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
// Instantiate the bean.--实例化beanBeanWrapper instanceWrapper = null;if (mbd.isSingleton()) { instanceWrapper = ve(bea // Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try {//调⽤MergedBeanDefin // Initialize the bean instance.--初始化bean实例Object exposedObject = bean;try {//如下⽅法很重要 populateBean(beanName, mbd, instanceWrapper); if (expose // Register bean { registerDisposableBeanIfNecessary(beanName, bean, mbd);}//...return exposedObject;}
④ populateBean
顾名思义,为bean实例属性赋值。
AbstractAutowireCapableBeanFactory.populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {//获取属性值列表PropertyValues pvs = PropertyValues();
//...该种符号表⽰暂时忽略其他代码
//在为bean属性赋值前,给InstantiationAwareBeanPostProcessors 机会修改bean的状态//应⽤场景如⽀持字段注⼊boolean continueWithPropertyPopulation = true; //循环调⽤InstantiationAwareBeanPostProcessors 的postProcessAfterInstantiation⽅法if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for if (!continueWithPropertyPopulation) { return;}//解析autowire注解字段,进⾏主动注⼊if (ResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_ // Add property values based on autowire by name if applicable. if (ResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowir // Add property values based on autowire by type if applicable. if (ResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireB pvs = newPvs;}boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck = (DependencyCheck() != RootBea
如下图所⽰在创建sqlSessionFactoryBean过程中会创建其属性globalConfiguration对象:
如下图所⽰在创建sqlSessionFactoryBean过程中(从左侧的⽅法顺序就可以看出来)会创建其属性PaginationInterceptor对象:
如下图所⽰在创建sqlSessionFactoryBean过程中(从左侧的⽅法顺序就可以看出来)会创建其属性SqlExplainInterceptor对象:
如下图所⽰在创建sqlSessionFactoryBean过程中(从左侧的⽅法顺序就可以看出来)会创建其属性PerformanceInterceptor对象:
如下图所⽰在创建sqlSessionFactoryBean过程中(从左侧的⽅法顺序就可以看出来)会创建其属性OptimisticLockerInterceptor对象:
⑤ initializeBean
AbstractAutowireCapableBeanFactory.initializeBean源码如下:css3圆角讲解
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (SecurityManager() != null) { AccessController Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //调⽤bean后置处理器的前置⽅法 wrappedBean = applyBeanPostProcessorsBeforeInitializ if (mbd == null || !mbd.isSynthetic()) { // //调⽤bean后置处理器的后置⽅法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanNam
AbstractAutowireCapableBeanFactory.invokeInitMethods⽅法源码如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet")
如下图所⽰,MybatisSqlSessionFactoryBean同样实现了InitializingBean接⼝。那么我们就需要注意
其afterPropertiesSet⽅法了。
>left join详解
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论