SpringBoot 为MapperScan添加动态扫描(占位符)功能

SpringBootLean 是对springboot学习与研究项目,是根据实际项目的形式对进行配置与处理,欢迎star与fork。 
[oschina 地址] 
http://git.oschina.net/cmlbeliever/SpringBootLearning 
[github 地址] 
https://github.com/cmlbeliever/SpringBootLearning

在对Mybatis自动扫描配置中,使用注解配置时,我们只要在@MapperScan中配置我们需要扫描的Mapper位置,大部分情况下是满足需求的。通常配置如下:

@MapperScan(basePackages = { "com.cml.springboot.sample.db" }, sqlSessionFactoryRef = "sqlSessionFactory")
 
 
  • 1

这样MapperScannerRegistrar就会去扫描com.cml.springboot.sample.db包下所有Mapper对象。

但是如果遇到需要动态配置扫描包,就有点麻烦了。

因为MapperScan是无法支持spring占位符功能。因为MapperScan注解功能的实现类MapperScannerRegistrar实现的是ImportBeanDefinitionRegistrar。在对@Configuration注解标记的类配置时,实现占位符功能的PropertyPlaceholderAutoConfiguration还没有开始加载。

作为拓展,那我们就可以自定义MapperScanner,实现接口EnvironmentAware,来添加占位符功能。主要代码也是参照MapperScannerRegistrar,主要是将

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

    //...省略代码
    List<String> basePackages = new ArrayList<String>();
    for (String pkg : annoAttrs.getStringArray("value")) {
      if (StringUtils.hasText(pkg)) {
        basePackages.add(pkg);
      }
    }
    for (String pkg : annoAttrs.getStringArray("basePackages")) {
      if (StringUtils.hasText(pkg)) {
        basePackages.add(pkg);
      }
    }
    for (Class<?> clazz : annoAttrs.getClassArray("basePackageClasses")) {
      basePackages.add(ClassUtils.getPackageName(clazz));
    }
      //...省略代码
  }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

改成

@Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

           //...省略代码

        List<String> basePackages = new ArrayList<String>();
        for (String pkg : annoAttrs.getStringArray("value")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(parsePlaceHolder(pkg));
            }
        }
        for (String pkg : annoAttrs.getStringArray("basePackages")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(parsePlaceHolder(pkg));
            }
        }
        for (Class<?> clazz : annoAttrs.getClassArray("basePackageClasses")) {
            basePackages.add(ClassUtils.getPackageName(clazz));
        }
           //...省略代码

    }
        private String parsePlaceHolder(String pro) {
        if (pro != null && pro.contains(PropertySourcesPlaceholderConfigurer.DEFAULT_PLACEHOLDER_PREFIX)) {
            String value = env.getProperty(pro.substring(2, pro.length() - 1));

            if (logger.isDebugEnabled()) {
                logger.debug("find placeholder value " + value + " for key " + pro);
            }

            if (null == value) {
                throw new IllegalArgumentException("property " + pro + " can not find!!!");
            }
            return value;
        }
        return pro;
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

使用时,只需要使用我们自定义的MapperScanner,并且配置basePackages

@MapperScanner(basePackages = { "${db.mybatis.mapperScanner.basePackage}" }, sqlSessionFactoryRef = "sqlSessionFactory")
 
 
  • 1

经过以上步骤,MapperScanner占位符功能添加成功。

使用场景分析:

  • 不想在代码上写死路径,而是通过配置文件配置Mapper位置
  • 在SpringApplication启动时,动态配置。结合SpringBatch可以实现只扫描当前batch下的Mapper功能

例如使用代码动态设置扫描路径

SpringApplication application = new SpringApplication(BootApplication.class);
        Map<String, Object> defaultProperties = new HashMap<>();
        defaultProperties.put("db.mybatis.mapperScanner.basePackage", "com.cml.springboot.batch."+batchId);
        application.setDefaultProperties(defaultProperties);
        application.setWebEnvironment(true);
        application.run(args);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中,占位符替换是通过使用PropertySourcesPlaceholderConfigurer来实现的。\[3\] PropertySourcesPlaceholderConfigurer是一个BeanFactoryPostProcessor,它可以解析属性文件中的占位符,并将其替换为相应的值。在Spring Boot中,占位符的默认格式是@@name@@,而不是传统的${name}。\[1\] 为了使用占位符替换,你需要在配置文件中指定占位符所代表的值,并告诉Spring Boot这个属性文件的位置。这可以通过在application.properties文件中设置相应的属性来实现。\[2\] 通过这种方式,你可以将分散在不同配置文件中的配置项的值集中到一个或多个属性文件中,方便管理和维护。 #### 引用[.reference_title] - *1* [记一次springboot工程占位符不能替换的问题](https://blog.csdn.net/meiye/article/details/123360313)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Spring自定义占位符替换(PropertyPlaceholderConfigurer)](https://blog.csdn.net/z69183787/article/details/52439658)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值