Browse Source

兼容mybatis的升级

miemie 3 years ago
parent
commit
5b892815b7

+ 0 - 4
mybatis-plus-boot-starter/src/main/java/com/baomidou/mybatisplus/autoconfigure/IdentifierGeneratorAutoConfiguration.java

@@ -30,10 +30,8 @@ import org.springframework.context.annotation.Lazy;
  */
 @Lazy
 @Configuration(proxyBeanMethods = false)
-@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
 public class IdentifierGeneratorAutoConfiguration {
 
-
     @Configuration(proxyBeanMethods = false)
     @ConditionalOnClass(InetUtils.class)
     public static class InetUtilsAutoConfig {
@@ -43,7 +41,5 @@ public class IdentifierGeneratorAutoConfiguration {
         public IdentifierGenerator identifierGenerator(InetUtils inetUtils) {
             return new DefaultIdentifierGenerator(inetUtils.findFirstNonLoopbackAddress());
         }
-
     }
-
 }

+ 53 - 12
mybatis-plus-boot-starter/src/main/java/com/baomidou/mybatisplus/autoconfigure/MybatisPlusAutoConfiguration.java

@@ -39,10 +39,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanWrapper;
 import org.springframework.beans.BeanWrapperImpl;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.beans.factory.*;
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
@@ -54,10 +52,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandi
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.ApplicationContext;
+import org.springframework.context.EnvironmentAware;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.env.Environment;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.ResourceLoader;
 import org.springframework.core.type.AnnotationMetadata;
@@ -112,11 +112,12 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
 
     private final List<ConfigurationCustomizer> configurationCustomizers;
 
+    private final List<SqlSessionFactoryBeanCustomizer> sqlSessionFactoryBeanCustomizers;
+
     private final List<MybatisPlusPropertiesCustomizer> mybatisPlusPropertiesCustomizers;
 
     private final ApplicationContext applicationContext;
 
-
     public MybatisPlusAutoConfiguration(MybatisPlusProperties properties,
                                         ObjectProvider<Interceptor[]> interceptorsProvider,
                                         ObjectProvider<TypeHandler[]> typeHandlersProvider,
@@ -124,6 +125,7 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
                                         ResourceLoader resourceLoader,
                                         ObjectProvider<DatabaseIdProvider> databaseIdProvider,
                                         ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider,
+                                        ObjectProvider<List<SqlSessionFactoryBeanCustomizer>> sqlSessionFactoryBeanCustomizers,
                                         ObjectProvider<List<MybatisPlusPropertiesCustomizer>> mybatisPlusPropertiesCustomizerProvider,
                                         ApplicationContext applicationContext) {
         this.properties = properties;
@@ -133,6 +135,7 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
         this.resourceLoader = resourceLoader;
         this.databaseIdProvider = databaseIdProvider.getIfAvailable();
         this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
+        this.sqlSessionFactoryBeanCustomizers = sqlSessionFactoryBeanCustomizers.getIfAvailable();
         this.mybatisPlusPropertiesCustomizers = mybatisPlusPropertiesCustomizerProvider.getIfAvailable();
         this.applicationContext = applicationContext;
     }
@@ -153,7 +156,6 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
         }
     }
 
-    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
     @Bean
     @ConditionalOnMissingBean
     public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
@@ -186,9 +188,8 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
         if (!ObjectUtils.isEmpty(this.typeHandlers)) {
             factory.setTypeHandlers(this.typeHandlers);
         }
-        Resource[] mapperLocations = this.properties.resolveMapperLocations();
-        if (!ObjectUtils.isEmpty(mapperLocations)) {
-            factory.setMapperLocations(mapperLocations);
+        if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
+            factory.setMapperLocations(this.properties.resolveMapperLocations());
         }
         // TODO 修改源码支持定义 TransactionFactory
         this.getBeanThen(TransactionFactory.class, factory::setTransactionFactory);
@@ -200,6 +201,8 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
         }
         Optional.ofNullable(defaultLanguageDriver).ifPresent(factory::setDefaultScriptingLanguageDriver);
 
+        applySqlSessionFactoryBeanCustomizers(factory);
+
         // TODO 此处必为非 NULL
         GlobalConfig globalConfig = this.properties.getGlobalConfig();
         // TODO 注入填充器
@@ -259,6 +262,14 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
         factory.setConfiguration(configuration);
     }
 
+    private void applySqlSessionFactoryBeanCustomizers(MybatisSqlSessionFactoryBean factory) {
+        if (!CollectionUtils.isEmpty(this.sqlSessionFactoryBeanCustomizers)) {
+            for (SqlSessionFactoryBeanCustomizer customizer : this.sqlSessionFactoryBeanCustomizers) {
+                customizer.customize(factory);
+            }
+        }
+    }
+
     @Bean
     @ConditionalOnMissingBean
     public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
@@ -270,15 +281,16 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
         }
     }
 
-
     /**
      * This will just scan the same base package as Spring Boot does. If you want more power, you can explicitly use
      * {@link org.mybatis.spring.annotation.MapperScan} but this will get typed mappers working correctly, out-of-the-box,
      * similar to using Spring Data JPA repositories.
      */
-    public static class AutoConfiguredMapperScannerRegistrar implements BeanFactoryAware, ImportBeanDefinitionRegistrar {
+    public static class AutoConfiguredMapperScannerRegistrar
+        implements BeanFactoryAware, EnvironmentAware, ImportBeanDefinitionRegistrar {
 
         private BeanFactory beanFactory;
+        private Environment environment;
 
         @Override
         public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
@@ -311,6 +323,25 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
                 // Need to mybatis-spring 2.0.6+
                 builder.addPropertyValue("defaultScope", "${mybatis-plus.mapper-default-scope:}");
             }
+
+            // for spring-native
+            boolean injectSqlSession = environment.getProperty("mybatis.inject-sql-session-on-mapper-scan", Boolean.class,
+                Boolean.TRUE);
+            if (injectSqlSession && this.beanFactory instanceof ListableBeanFactory) {
+                ListableBeanFactory listableBeanFactory = (ListableBeanFactory) this.beanFactory;
+                Optional<String> sqlSessionTemplateBeanName = Optional
+                    .ofNullable(getBeanNameForType(SqlSessionTemplate.class, listableBeanFactory));
+                Optional<String> sqlSessionFactoryBeanName = Optional
+                    .ofNullable(getBeanNameForType(SqlSessionFactory.class, listableBeanFactory));
+                if (sqlSessionTemplateBeanName.isPresent() || !sqlSessionFactoryBeanName.isPresent()) {
+                    builder.addPropertyValue("sqlSessionTemplateBeanName",
+                        sqlSessionTemplateBeanName.orElse("sqlSessionTemplate"));
+                } else {
+                    builder.addPropertyValue("sqlSessionFactoryBeanName", sqlSessionFactoryBeanName.get());
+                }
+            }
+            builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+
             registry.registerBeanDefinition(MapperScannerConfigurer.class.getName(), builder.getBeanDefinition());
         }
 
@@ -318,13 +349,23 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
         public void setBeanFactory(BeanFactory beanFactory) {
             this.beanFactory = beanFactory;
         }
+
+        @Override
+        public void setEnvironment(Environment environment) {
+            this.environment = environment;
+        }
+
+        private String getBeanNameForType(Class<?> type, ListableBeanFactory factory) {
+            String[] beanNames = factory.getBeanNamesForType(type);
+            return beanNames.length > 0 ? beanNames[0] : null;
+        }
     }
 
     /**
      * If mapper registering configuration or mapper scanning configuration not present, this configuration allow to scan
      * mappers based on the same component-scanning path as Spring Boot itself.
      */
-    @Configuration(proxyBeanMethods = false)
+    @org.springframework.context.annotation.Configuration
     @Import(AutoConfiguredMapperScannerRegistrar.class)
     @ConditionalOnMissingBean({MapperFactoryBean.class, MapperScannerConfigurer.class})
     public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {

+ 4 - 7
mybatis-plus-boot-starter/src/main/java/com/baomidou/mybatisplus/autoconfigure/MybatisPlusLanguageDriverAutoConfiguration.java

@@ -49,10 +49,7 @@ public class MybatisPlusLanguageDriverAutoConfiguration {
 
     private static final String CONFIGURATION_PROPERTY_PREFIX = Constants.MYBATIS_PLUS + ".scripting-language-driver";
 
-    /**
-     * Configuration class for mybatis-freemarker 1.1.x or under.
-     */
-    @Configuration(proxyBeanMethods = false)
+    @Configuration
     @ConditionalOnClass(FreeMarkerLanguageDriver.class)
     @ConditionalOnMissingClass("org.mybatis.scripting.freemarker.FreeMarkerLanguageDriverConfig")
     public static class LegacyFreeMarkerConfiguration {
@@ -66,7 +63,7 @@ public class MybatisPlusLanguageDriverAutoConfiguration {
     /**
      * Configuration class for mybatis-freemarker 1.2.x or above.
      */
-    @Configuration(proxyBeanMethods = false)
+    @Configuration
     @ConditionalOnClass({FreeMarkerLanguageDriver.class, FreeMarkerLanguageDriverConfig.class})
     public static class FreeMarkerConfiguration {
         @Bean
@@ -86,7 +83,7 @@ public class MybatisPlusLanguageDriverAutoConfiguration {
     /**
      * Configuration class for mybatis-velocity 2.1.x or above.
      */
-    @Configuration(proxyBeanMethods = false)
+    @Configuration
     @ConditionalOnClass({VelocityLanguageDriver.class, VelocityLanguageDriverConfig.class})
     public static class VelocityConfiguration {
         @Bean
@@ -103,7 +100,7 @@ public class MybatisPlusLanguageDriverAutoConfiguration {
         }
     }
 
-    @Configuration(proxyBeanMethods = false)
+    @Configuration
     @ConditionalOnClass(ThymeleafLanguageDriver.class)
     public static class ThymeleafConfiguration {
         @Bean

+ 2 - 3
mybatis-plus-boot-starter/src/main/java/com/baomidou/mybatisplus/autoconfigure/SpringBootVFS.java

@@ -16,7 +16,6 @@
 package com.baomidou.mybatisplus.autoconfigure;
 
 
-import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import org.apache.ibatis.io.VFS;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@@ -50,7 +49,7 @@ public class SpringBootVFS extends VFS {
     private static String preserveSubpackageName(final String baseUrlString, final Resource resource,
                                                  final String rootPath) {
         try {
-            return rootPath + (rootPath.endsWith(StringPool.SLASH) ? StringPool.EMPTY : StringPool.SLASH)
+            return rootPath + (rootPath.endsWith("/") ? "" : "/")
                 + resource.getURL().toString().substring(baseUrlString.length());
         } catch (IOException e) {
             throw new UncheckedIOException(e);
@@ -60,7 +59,7 @@ public class SpringBootVFS extends VFS {
     @Override
     protected List<String> list(URL url, String path) throws IOException {
         String urlString = url.toString();
-        String baseUrlString = urlString.endsWith(StringPool.SLASH) ? urlString : urlString.concat(StringPool.SLASH);
+        String baseUrlString = urlString.endsWith("/") ? urlString : urlString.concat("/");
         Resource[] resources = resourceResolver.getResources(baseUrlString + "**/*.class");
         return Stream.of(resources).map(resource -> preserveSubpackageName(baseUrlString, resource, path))
             .collect(Collectors.toList());

+ 35 - 0
mybatis-plus-boot-starter/src/main/java/com/baomidou/mybatisplus/autoconfigure/SqlSessionFactoryBeanCustomizer.java

@@ -0,0 +1,35 @@
+/*
+ *    Copyright 2015-2022 the original author or authors.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+package com.baomidou.mybatisplus.autoconfigure;
+
+import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
+
+/**
+ * Callback interface that can be customized a {@link MybatisSqlSessionFactoryBean} object generated on auto-configuration.
+ *
+ * @author Kazuki Shimizu
+ * @since 2.2.2
+ */
+@FunctionalInterface
+public interface SqlSessionFactoryBeanCustomizer {
+
+    /**
+     * Customize the given a {@link MybatisSqlSessionFactoryBean} object.
+     *
+     * @param factoryBean the factory bean object to customize
+     */
+    void customize(MybatisSqlSessionFactoryBean factoryBean);
+}

+ 18 - 2
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/spring/MybatisSqlSessionFactoryBean.java

@@ -114,6 +114,9 @@ public class MybatisSqlSessionFactoryBean implements FactoryBean<SqlSessionFacto
 
     private String typeHandlersPackage;
 
+    @SuppressWarnings("rawtypes")
+    private Class<? extends TypeHandler> defaultEnumTypeHandler;
+
     private Class<?>[] typeAliases;
 
     private String typeAliasesPackage;
@@ -271,6 +274,17 @@ public class MybatisSqlSessionFactoryBean implements FactoryBean<SqlSessionFacto
         this.typeHandlersPackage = typeHandlersPackage;
     }
 
+    /**
+     * Set the default type handler class for enum.
+     *
+     * @param defaultEnumTypeHandler The default type handler class for enum
+     * @since 2.0.5
+     */
+    public void setDefaultEnumTypeHandler(
+        @SuppressWarnings("rawtypes") Class<? extends TypeHandler> defaultEnumTypeHandler) {
+        this.defaultEnumTypeHandler = defaultEnumTypeHandler;
+    }
+
     /**
      * Set type handlers. They must be annotated with {@code MappedTypes} and optionally with {@code MappedJdbcTypes}
      *
@@ -510,14 +524,16 @@ public class MybatisSqlSessionFactoryBean implements FactoryBean<SqlSessionFacto
             });
         }
 
+        targetConfiguration.setDefaultEnumTypeHandler(defaultEnumTypeHandler);
+
         if (!isEmpty(this.scriptingLanguageDrivers)) {
             Stream.of(this.scriptingLanguageDrivers).forEach(languageDriver -> {
                 targetConfiguration.getLanguageRegistry().register(languageDriver);
                 LOGGER.debug(() -> "Registered scripting language driver: '" + languageDriver + "'");
             });
         }
-
-        Optional.ofNullable(this.defaultScriptingLanguageDriver).ifPresent(targetConfiguration::setDefaultScriptingLanguage);
+        Optional.ofNullable(this.defaultScriptingLanguageDriver)
+            .ifPresent(targetConfiguration::setDefaultScriptingLanguage);
 
         if (this.databaseIdProvider != null) {// fix #64 set databaseId before parse mapper xmls
             try {