abel533 / Mapper

Mybatis Common Mapper - Easy to use
https://mybatis.io
MIT License
7.32k stars 1.63k forks source link

MapperScan初始化时,Spring的Enviroment注入错误导致属性无法注入 #828

Open linzhiqiang0514 opened 3 years ago

linzhiqiang0514 commented 3 years ago

配置如下:

@Configuration
@MapperScan({"com.xxxx.**.mapper*", "${mybatis.scan.pkg1:com.temp1.**.mapper*}",
    "${mybatis.scan.pkg2:com.temp2.*.mapper*}"})
public class MybatisConfig {
}

在application.yml中注入属性:

mybatis.scan.pkg1=cn.test.**.mapper*

发现实际不生效。

经过代码跟踪: Spring在处理这个包转换时 位置在:org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#resolveBasePackage

protected String resolveBasePackage(String basePackage) {
        return ClassUtils.convertClassNameToResourcePath(getEnvironment().resolveRequiredPlaceholders(basePackage));
    }

这个getEnvironment的属性来源于:org.springframework.context.annotation.ClassPathBeanDefinitionScanner#getOrCreateEnvironment

    /**
     * Get the Environment from the given registry if possible, otherwise return a new
     * StandardEnvironment.
     */
    private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        if (registry instanceof EnvironmentCapable) {
            return ((EnvironmentCapable) registry).getEnvironment();
        }
        return new StandardEnvironment();
    }

根原因为: tk.mybatis.spring.annotation.MapperScannerRegistrar

@Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
        ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);

建议修改为:

@Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
        ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry,true,this.enviroment);

或者,调用

scanner.setEnviroment(this.enviroment);
woshibendanbuyaodawo commented 3 weeks ago

我也遇到了,有解决办法吗