浅析mybatisPlus启动流程

本文详细解读MybatisPlusAutoConfiguration与Mybatis的区别,涉及自定义配置、SqlSessionFactory的替换,以及MybatisMapperAnnotationBuilder如何增强CRUD操作。核心内容包括配置类修改、初始化流程和关键组件的注入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文中都是与mybatis-spring比较,与之相同之处,本文不再赘述。
对于启动流程不清楚的,可参考浅析MybatisAutoConfiguration流程

1. MybatisPlusAutoConfiguration

区别MybatisAutoConfiguration:

  1. 类注解部分引入的配置类换成了MybatisPlus定义的。
  2. afterPropertiesSet方法多了一步设置自定义配置的过程
  3. sqlSessionFactory内部变更,使用MybatisSqlSessionFactoryBean替代MybatisSessionFactoryBean
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisPlusProperties.class)
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisPlusLanguageDriverAutoConfiguration.class})
public class MybatisPlusAutoConfiguration implements InitializingBean {

	@Override
    public void afterPropertiesSet() {
    	// 这里可以实现自定义操作,例如设置主键生成策略
        if (!CollectionUtils.isEmpty(mybatisPlusPropertiesCustomizers)){
            mybatisPlusPropertiesCustomizers.forEach(i -> i.customize(properties));
        }
        checkConfigFileExists();
    }
    
    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        // 使用 MybatisSqlSessionFactoryBean 而不是 SqlSessionFactoryBean
        MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
        // 省略常规配置
        .......
        // 此处必为非 NULL
        GlobalConfig globalConfig = this.properties.getGlobalConfig();
        // 注入填充器
        this.getBeanThen(MetaObjectHandler.class, globalConfig::setMetaObjectHandler);
        // 注入主键生成器
        this.getBeanThen(IKeyGenerator.class, i -> globalConfig.getDbConfig().setKeyGenerator(i));
        // 注入sql注入器
        this.getBeanThen(ISqlInjector.class, globalConfig::setSqlInjector);
        // 注入ID生成器
        this.getBeanThen(IdentifierGenerator.class, globalConfig::setIdentifierGenerator);
        // 设置 GlobalConfig 到 MybatisSqlSessionFactoryBean
        factory.setGlobalConfig(globalConfig);
        return factory.getObject();
    }
}

2.MybatisMapperAnnotationBuilder

MybatisSqlSessionFactoryBean的buildSqlSessionFactory方法类似,这里就不重复说明了。
沿着MybatisSqlSessionFactoryBean调用顺序(如下图),直接看MybatisMapperAnnotationBuilder的parse方法。
MybatisMapperAnnotationBuilder.parse方法是在

对应于MapperAnnotationBuilder用于解析dao接口上的注解等信息,MybatisMapperAnnotationBuilder不仅实现上述功能,而且再这里注入了通用的crud操作。

public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {

 	@Override
    public void parse() {
        String resource = type.toString();
        if (!configuration.isResourceLoaded(resource)) {
        	// 解析dao接口对应的xml文件,如果解析过则略过
            loadXmlResource();
            // 标识解析过资源了
            configuration.addLoadedResource(resource);
            final String typeName = type.getName();
            assistant.setCurrentNamespace(typeName);
            parseCache();
            parseCacheRef();
            SqlParserHelper.initSqlParserInfoCache(type);
            Method[] methods = type.getMethods();
            // 解析方法上的注解
            for (Method method : methods) {
                try {
                    if (!method.isBridge()) {
                        parseStatement(method);
                        SqlParserHelper.initSqlParserInfoCache(typeName, method);
                    }
                } catch (IncompleteElementException e) {
                	// 解析失败的后面会再次尝试解析
                    configuration.addIncompleteMethod(new MybatisMethodResolver(this, method));
                }
            }
			// 重点 MybatisPuls 自动注入crud
            if (GlobalConfigUtils.isSupperMapperChildren(configuration, type)) {
                GlobalConfigUtils.getSqlInjector(configuration).inspectInject(assistant, type);
            }
        }
        parsePendingMethods();
    }
}

接着看看AbstractSqlInjector类inspectInject方法

public abstract class AbstractSqlInjector implements ISqlInjector {

    @Override
    public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
        Class<?> modelClass = extractModelClass(mapperClass);
        if (modelClass != null) {
            String className = mapperClass.toString();
            Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
            if (!mapperRegistryCache.contains(className)) {
            	// 这里可以重写getMethodList,定制属于自己的通用方法
                List<AbstractMethod> methodList = this.getMethodList(mapperClass);
                if (CollectionUtils.isNotEmpty(methodList)) {
                	// 映射解析table信息
                    TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);
                    // 循环注入自定义方法
                    methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));
                } else {
                    logger.debug(mapperClass.toString() + ", No effective injection method was found.");
                }
                mapperRegistryCache.add(className);
            }
        }
    }
}

MybatisPlus启动过程中,做的初始化操作主要是上面这些地方。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值