Skip to content

Commit ba522d5

Browse files
committed
Change to support spring-native
* Set sqlSessionTemplateBeanName or sqlSessionFactoryBeanName at scanning mapper * Add new configuration property for configure inject sql session on mapper scan * Update mybatis-spring 2.0.7-SNAPSHOT See gh-617
1 parent 73b74dc commit ba522d5

File tree

6 files changed

+123
-14
lines changed

6 files changed

+123
-14
lines changed

mybatis-spring-boot-autoconfigure/src/main/java/org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.java

+38-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2021 the original author or authors.
2+
* Copyright 2015-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717

1818
import java.beans.PropertyDescriptor;
1919
import java.util.List;
20+
import java.util.Optional;
2021
import java.util.Set;
2122
import java.util.stream.Collectors;
2223
import java.util.stream.Stream;
@@ -42,7 +43,9 @@
4243
import org.springframework.beans.factory.BeanFactory;
4344
import org.springframework.beans.factory.BeanFactoryAware;
4445
import org.springframework.beans.factory.InitializingBean;
46+
import org.springframework.beans.factory.ListableBeanFactory;
4547
import org.springframework.beans.factory.ObjectProvider;
48+
import org.springframework.beans.factory.config.BeanDefinition;
4649
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
4750
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
4851
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
@@ -53,9 +56,11 @@
5356
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
5457
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
5558
import org.springframework.boot.context.properties.EnableConfigurationProperties;
59+
import org.springframework.context.EnvironmentAware;
5660
import org.springframework.context.annotation.Bean;
5761
import org.springframework.context.annotation.Import;
5862
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
63+
import org.springframework.core.env.Environment;
5964
import org.springframework.core.io.Resource;
6065
import org.springframework.core.io.ResourceLoader;
6166
import org.springframework.core.type.AnnotationMetadata;
@@ -208,9 +213,11 @@ public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory
208213
* {@link org.mybatis.spring.annotation.MapperScan} but this will get typed mappers working correctly, out-of-the-box,
209214
* similar to using Spring Data JPA repositories.
210215
*/
211-
public static class AutoConfiguredMapperScannerRegistrar implements BeanFactoryAware, ImportBeanDefinitionRegistrar {
216+
public static class AutoConfiguredMapperScannerRegistrar
217+
implements BeanFactoryAware, EnvironmentAware, ImportBeanDefinitionRegistrar {
212218

213219
private BeanFactory beanFactory;
220+
private Environment environment;
214221

215222
@Override
216223
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
@@ -242,6 +249,25 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
242249
// Need to mybatis-spring 2.0.6+
243250
builder.addPropertyValue("defaultScope", "${mybatis.mapper-default-scope:}");
244251
}
252+
253+
// for spring-native
254+
boolean injectSqlSession = environment.getProperty("mybatis.inject-sql-session-on-mapper-scan", Boolean.class,
255+
Boolean.TRUE);
256+
if (injectSqlSession && this.beanFactory instanceof ListableBeanFactory) {
257+
ListableBeanFactory listableBeanFactory = (ListableBeanFactory) this.beanFactory;
258+
Optional<String> sqlSessionTemplateBeanName = Optional
259+
.ofNullable(getBeanNameForType(SqlSessionTemplate.class, listableBeanFactory));
260+
Optional<String> sqlSessionFactoryBeanName = Optional
261+
.ofNullable(getBeanNameForType(SqlSessionFactory.class, listableBeanFactory));
262+
if (sqlSessionTemplateBeanName.isPresent() || !sqlSessionFactoryBeanName.isPresent()) {
263+
builder.addPropertyValue("sqlSessionTemplateBeanName",
264+
sqlSessionTemplateBeanName.orElse("sqlSessionTemplate"));
265+
} else {
266+
builder.addPropertyValue("sqlSessionFactoryBeanName", sqlSessionFactoryBeanName.get());
267+
}
268+
}
269+
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
270+
245271
registry.registerBeanDefinition(MapperScannerConfigurer.class.getName(), builder.getBeanDefinition());
246272
}
247273

@@ -250,6 +276,16 @@ public void setBeanFactory(BeanFactory beanFactory) {
250276
this.beanFactory = beanFactory;
251277
}
252278

279+
@Override
280+
public void setEnvironment(Environment environment) {
281+
this.environment = environment;
282+
}
283+
284+
private String getBeanNameForType(Class<?> type, ListableBeanFactory factory) {
285+
String[] beanNames = factory.getBeanNamesForType(type);
286+
return beanNames.length > 0 ? beanNames[0] : null;
287+
}
288+
253289
}
254290

255291
/**

mybatis-spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
"description": "A default scope for mapper bean that scanned by auto-configure.",
3131
"type": "java.lang.String"
3232
},
33+
{
34+
"defaultValue": true,
35+
"name": "mybatis.inject-sql-session-on-mapper-scan",
36+
"description": "Set whether inject a SqlSessionTemplate or SqlSessionFactory bean (If you want to back to the behavior of 2.2.1 or before, specify false). If you use together with spring-native, should be set true.",
37+
"type": "java.lang.Boolean"
38+
},
3339
{
3440
"name": "mybatis.scripting-language-driver.velocity.userdirective",
3541
"deprecation": {

mybatis-spring-boot-autoconfigure/src/site/markdown/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ Available properties are:
150150
| `configuration-properties` | Externalized properties for MyBatis configuration. Specified properties can be used as placeholder on MyBatis config file and Mapper file. For detail see the [MyBatis reference page](http://www.mybatis.org/mybatis-3/configuration.html#properties). |
151151
| `lazy-initialization` | Whether enable lazy initialization of mapper bean. Set `true` to enable lazy initialization. This feature requires to use together with mybatis-spring 2.0.2+. |
152152
| `mapper-default-scope` | Default scope for mapper bean that scanned by auto-configure. This feature requires to use together with mybatis-spring 2.0.6+. |
153+
| `mybatis.inject-sql-session-on-mapper-scan` | Set whether inject a `SqlSessionTemplate` or `SqlSessionFactory` bean (If you want to back to the behavior of 2.2.1 or before, specify `false`). If you use together with spring-native, should be set `true`(default). |
153154
| `configuration.*` | Property keys for `Configuration` bean provided by MyBatis Core. About available nested properties see the [MyBatis reference page](http://www.mybatis.org/mybatis-3/configuration.html#settings). <span class="label important">NOTE</span>: This property cannot be used at the same time with the `config-location`. |
154155
| `scripting-language-driver.thymeleaf.*` | Property keys for `ThymeleafLanguageDriverConfig` bean provided by MyBatis Thymeleaf. About available nested properties see the [MyBatis Thymeleaf reference page](http://www.mybatis.org/thymeleaf-scripting/user-guide.html#_configuration_properties). |
155156
| `scripting-language-driver.freemarker.*` | Properties keys for `FreeMarkerLanguageDriverConfig` bean provided by MyBatis FreeMarker. About available nested properties see the [MyBatis FreeMarker reference page](http://www.mybatis.org/freemarker-scripting/#Configuration). This feature requires to use together with mybatis-freemarker 1.2.0+. |

mybatis-spring-boot-autoconfigure/src/test/java/org/mybatis/spring/boot/autoconfigure/AdditionalConfigurationMetadataTest.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2021 the original author or authors.
2+
* Copyright 2015-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -45,7 +45,7 @@ void testProperties() throws IOException {
4545

4646
List<Map<String, Object>> properties = documentContext.read("$.properties");
4747

48-
assertAll(() -> assertThat(properties.size()).isEqualTo(5), () -> {
48+
assertAll(() -> assertThat(properties.size()).isEqualTo(6), () -> {
4949
// assert for mybatis.configuration.default-scripting-language
5050
Map<String, Object> element = properties.get(0);
5151
assertThat(element.get("sourceType")).isEqualTo("org.apache.ibatis.session.Configuration");
@@ -78,8 +78,14 @@ void testProperties() throws IOException {
7878
assertThat(element.get("name")).isEqualTo("mybatis.mapper-default-scope");
7979
assertThat(element.get("type")).isEqualTo("java.lang.String");
8080
}, () -> {
81-
// assert for mybatis.scripting-language-driver.velocity.userdirective
81+
// assert for mybatis.inject-sql-session-on-mapper-scan
8282
Map<String, Object> element = properties.get(4);
83+
assertThat(element.get("defaultValue")).isEqualTo(true);
84+
assertThat(element.get("name")).isEqualTo("mybatis.inject-sql-session-on-mapper-scan");
85+
assertThat(element.get("type")).isEqualTo("java.lang.Boolean");
86+
}, () -> {
87+
// assert for mybatis.scripting-language-driver.velocity.userdirective
88+
Map<String, Object> element = properties.get(5);
8389
assertThat(element.get("name")).isEqualTo("mybatis.scripting-language-driver.velocity.userdirective");
8490
@SuppressWarnings("unchecked")
8591
Map<String, Object> deprecation = (Map<String, Object>) element.get("deprecation");

mybatis-spring-boot-autoconfigure/src/test/java/org/mybatis/spring/boot/autoconfigure/MybatisAutoConfigurationTest.java

+67-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2021 the original author or authors.
2+
* Copyright 2015-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -75,6 +75,7 @@
7575
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
7676
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
7777
import org.springframework.beans.factory.config.PropertiesFactoryBean;
78+
import org.springframework.beans.factory.config.RuntimeBeanReference;
7879
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
7980
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
8081
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
@@ -183,6 +184,46 @@ void testScanWithLazy() {
183184
assertThat(sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers()).hasSize(1);
184185
}
185186

187+
@Test
188+
void testAutoScanWithDefault() {
189+
this.context.register(EmbeddedDataSourceConfiguration.class, MybatisBootMapperScanAutoConfiguration.class,
190+
MybatisAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
191+
this.context.refresh();
192+
SqlSessionFactory sqlSessionFactory = this.context.getBean(SqlSessionFactory.class);
193+
assertThat(this.context.getBeanNamesForType(SqlSessionFactory.class)).hasSize(1);
194+
assertThat(this.context.getBeanNamesForType(SqlSessionTemplate.class)).hasSize(1);
195+
assertThat(this.context.getBeanNamesForType(CityMapper.class)).hasSize(1);
196+
assertThat(this.context.getBean(SqlSessionTemplate.class).getExecutorType()).isEqualTo(ExecutorType.SIMPLE);
197+
assertThat(this.context.getBean(SqlSessionFactory.class).getConfiguration().isMapUnderscoreToCamelCase()).isFalse();
198+
this.context.getBean(CityMapper.class);
199+
assertThat(sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers()).hasSize(1);
200+
assertThat(((RuntimeBeanReference) this.context.getBeanDefinition("cityMapper").getPropertyValues()
201+
.getPropertyValue("sqlSessionTemplate").getValue()).getBeanName()).isEqualTo("sqlSessionTemplate");
202+
assertThat(
203+
this.context.getBeanDefinition(this.context.getBeanNamesForType(MapperScannerConfigurer.class)[0]).getRole())
204+
.isEqualTo(BeanDefinition.ROLE_INFRASTRUCTURE);
205+
}
206+
207+
@Test
208+
void testAutoScanWithInjectSqlSessionOnMapperScanIsFalse() {
209+
TestPropertyValues.of("mybatis.inject-sql-session-on-mapper-scan:false").applyTo(this.context);
210+
this.context.register(EmbeddedDataSourceConfiguration.class, MybatisBootMapperScanAutoConfiguration.class,
211+
MybatisAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
212+
this.context.refresh();
213+
SqlSessionFactory sqlSessionFactory = this.context.getBean(SqlSessionFactory.class);
214+
assertThat(this.context.getBeanNamesForType(SqlSessionFactory.class)).hasSize(1);
215+
assertThat(this.context.getBeanNamesForType(SqlSessionTemplate.class)).hasSize(1);
216+
assertThat(this.context.getBeanNamesForType(CityMapper.class)).hasSize(1);
217+
assertThat(this.context.getBean(SqlSessionTemplate.class).getExecutorType()).isEqualTo(ExecutorType.SIMPLE);
218+
assertThat(this.context.getBean(SqlSessionFactory.class).getConfiguration().isMapUnderscoreToCamelCase()).isFalse();
219+
this.context.getBean(CityMapper.class);
220+
assertThat(sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers()).hasSize(1);
221+
assertThat(this.context.getBeanDefinition("cityMapper").getPropertyValues().getPropertyValue("sqlSessionTemplate"))
222+
.isNull();
223+
assertThat(this.context.getBeanDefinition("cityMapper").getPropertyValues().getPropertyValue("sqlSessionFactory"))
224+
.isNull();
225+
}
226+
186227
@Test
187228
void testAutoScanWithLazy() {
188229
TestPropertyValues.of("mybatis.lazy-initialization:true").applyTo(this.context);
@@ -601,12 +642,15 @@ void testWithConfigurationVariablesAndPropertiesSameKey() {
601642

602643
@Test
603644
void testCustomSqlSessionFactory() {
604-
this.context.register(EmbeddedDataSourceConfiguration.class, MybatisAutoConfiguration.class,
605-
CustomSqlSessionFactoryConfiguration.class);
645+
this.context.register(EmbeddedDataSourceConfiguration.class, MybatisBootMapperScanAutoConfiguration.class,
646+
CustomSqlSessionFactoryConfiguration.class, MybatisAutoConfiguration.class);
606647
this.context.refresh();
607648
assertThat(this.context.getBeanNamesForType(SqlSessionFactory.class)).hasSize(1);
608649
assertThat(this.context.getBean(SqlSessionFactory.class).getConfiguration().getVariables().getProperty("key"))
609650
.isEqualTo("value");
651+
assertThat(this.context.getBeanNamesForType(CityMapper.class)).hasSize(1);
652+
assertThat(((RuntimeBeanReference) this.context.getBeanDefinition("cityMapper").getPropertyValues()
653+
.getPropertyValue("sqlSessionFactory").getValue()).getBeanName()).isEqualTo("customSqlSessionFactory");
610654
}
611655

612656
@Test
@@ -620,11 +664,14 @@ void testMySqlSessionFactory() {
620664

621665
@Test
622666
void testCustomSqlSessionTemplate() {
623-
this.context.register(EmbeddedDataSourceConfiguration.class, MybatisAutoConfiguration.class,
624-
CustomSqlSessionTemplateConfiguration.class);
667+
this.context.register(EmbeddedDataSourceConfiguration.class, MybatisBootMapperScanAutoConfiguration.class,
668+
CustomSqlSessionTemplateConfiguration.class, MybatisAutoConfiguration.class);
625669
this.context.refresh();
626670
assertThat(this.context.getBeanNamesForType(SqlSessionTemplate.class)).hasSize(1);
627671
assertThat(this.context.getBean(SqlSessionTemplate.class).getExecutorType()).isEqualTo(ExecutorType.BATCH);
672+
assertThat(this.context.getBeanNamesForType(CityMapper.class)).hasSize(1);
673+
assertThat(((RuntimeBeanReference) this.context.getBeanDefinition("cityMapper").getPropertyValues()
674+
.getPropertyValue("sqlSessionTemplate").getValue()).getBeanName()).isEqualTo("customSqlSessionTemplate");
628675
}
629676

630677
@Test
@@ -636,6 +683,19 @@ void testMySqlSessionTemplate() {
636683
assertThat(this.context.getBean(SqlSessionTemplate.class)).isInstanceOf(MySqlSessionTemplate.class);
637684
}
638685

686+
@Test
687+
void testCustomSqlSessionTemplateAndSqlSessionFactory() {
688+
this.context.register(EmbeddedDataSourceConfiguration.class, MybatisBootMapperScanAutoConfiguration.class,
689+
CustomSqlSessionFactoryConfiguration.class, CustomSqlSessionTemplateConfiguration.class,
690+
MybatisAutoConfiguration.class);
691+
this.context.refresh();
692+
assertThat(this.context.getBeanNamesForType(SqlSessionTemplate.class)).hasSize(1);
693+
assertThat(this.context.getBean(SqlSessionTemplate.class).getExecutorType()).isEqualTo(ExecutorType.BATCH);
694+
assertThat(this.context.getBeanNamesForType(CityMapper.class)).hasSize(1);
695+
assertThat(((RuntimeBeanReference) this.context.getBeanDefinition("cityMapper").getPropertyValues()
696+
.getPropertyValue("sqlSessionTemplate").getValue()).getBeanName()).isEqualTo("customSqlSessionTemplate");
697+
}
698+
639699
@Test
640700
void testTypeAliasesSuperTypeIsSpecify() {
641701
TestPropertyValues
@@ -965,7 +1025,7 @@ public VendorDatabaseIdProvider vendorDatabaseIdProvider(Properties vendorProper
9651025
@Configuration
9661026
static class CustomSqlSessionFactoryConfiguration {
9671027
@Bean
968-
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
1028+
public SqlSessionFactory customSqlSessionFactory(DataSource dataSource) throws Exception {
9691029
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
9701030
sqlSessionFactoryBean.setDataSource(dataSource);
9711031
Properties props = new Properties();
@@ -989,7 +1049,7 @@ public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {
9891049
@Configuration
9901050
static class CustomSqlSessionTemplateConfiguration {
9911051
@Bean
992-
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
1052+
public SqlSessionTemplate customSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
9931053
return new SqlSessionTemplate(sqlSessionFactory, ExecutorType.BATCH);
9941054
}
9951055
}

pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
4-
Copyright 2015-2021 the original author or authors.
4+
Copyright 2015-2022 the original author or authors.
55
66
Licensed under the Apache License, Version 2.0 (the "License");
77
you may not use this file except in compliance with the License.
@@ -68,7 +68,7 @@
6868

6969
<properties>
7070
<mybatis.version>3.5.9</mybatis.version>
71-
<mybatis-spring.version>2.0.6</mybatis-spring.version>
71+
<mybatis-spring.version>2.0.7-SNAPSHOT</mybatis-spring.version>
7272
<mybatis-freemarker.version>1.2.3</mybatis-freemarker.version>
7373
<mybatis-velocity.version>2.1.1</mybatis-velocity.version>
7474
<mybatis-thymeleaf.version>1.0.3</mybatis-thymeleaf.version>

0 commit comments

Comments
 (0)