Skip to content

Commit 29bf471

Browse files
authored
Merge pull request #326 from kazuki43zoo/gh-325
Support enable/disable lazy Initialization on mapper scanning feature
2 parents 2911ee4 + 703fcea commit 29bf471

File tree

6 files changed

+90
-23
lines changed

6 files changed

+90
-23
lines changed

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

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.mybatis.spring.boot.autoconfigure;
1717

1818
import java.util.List;
19+
import java.util.stream.Stream;
1920

2021
import javax.sql.DataSource;
2122

@@ -28,15 +29,18 @@
2829
import org.apache.ibatis.type.TypeHandler;
2930
import org.mybatis.spring.SqlSessionFactoryBean;
3031
import org.mybatis.spring.SqlSessionTemplate;
31-
import org.mybatis.spring.mapper.ClassPathMapperScanner;
3232
import org.mybatis.spring.mapper.MapperFactoryBean;
33+
import org.mybatis.spring.mapper.MapperScannerConfigurer;
3334
import org.slf4j.Logger;
3435
import org.slf4j.LoggerFactory;
3536

37+
import org.springframework.beans.BeanWrapper;
38+
import org.springframework.beans.BeanWrapperImpl;
3639
import org.springframework.beans.factory.BeanFactory;
3740
import org.springframework.beans.factory.BeanFactoryAware;
3841
import org.springframework.beans.factory.InitializingBean;
3942
import org.springframework.beans.factory.ObjectProvider;
43+
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
4044
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
4145
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
4246
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -46,7 +50,6 @@
4650
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
4751
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
4852
import org.springframework.boot.context.properties.EnableConfigurationProperties;
49-
import org.springframework.context.ResourceLoaderAware;
5053
import org.springframework.context.annotation.Bean;
5154
import org.springframework.context.annotation.Import;
5255
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
@@ -190,12 +193,10 @@ public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory
190193
* repositories.
191194
*/
192195
public static class AutoConfiguredMapperScannerRegistrar
193-
implements BeanFactoryAware, ImportBeanDefinitionRegistrar, ResourceLoaderAware {
196+
implements BeanFactoryAware, ImportBeanDefinitionRegistrar {
194197

195198
private BeanFactory beanFactory;
196199

197-
private ResourceLoader resourceLoader;
198-
199200
@Override
200201
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
201202

@@ -211,25 +212,23 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
211212
packages.forEach(pkg -> logger.debug("Using auto-configuration base package '{}'", pkg));
212213
}
213214

214-
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
215-
if (this.resourceLoader != null) {
216-
scanner.setResourceLoader(this.resourceLoader);
217-
}
218-
scanner.setAnnotationClass(Mapper.class);
219-
scanner.registerFilters();
220-
scanner.doScan(StringUtils.toStringArray(packages));
221-
215+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
216+
builder.addPropertyValue("processPropertyPlaceHolders", true);
217+
builder.addPropertyValue("annotationClass", Mapper.class);
218+
builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(packages));
219+
BeanWrapper beanWrapper = new BeanWrapperImpl(MapperScannerConfigurer.class);
220+
Stream.of(beanWrapper.getPropertyDescriptors())
221+
// Need to mybatis-spring 2.0.2+
222+
.filter(x -> x.getName().equals("lazyInitialization")).findAny()
223+
.ifPresent(x -> builder.addPropertyValue("lazyInitialization", "${mybatis.lazy-initialization:false}"));
224+
registry.registerBeanDefinition(MapperScannerConfigurer.class.getName(), builder.getBeanDefinition());
222225
}
223226

224227
@Override
225228
public void setBeanFactory(BeanFactory beanFactory) {
226229
this.beanFactory = beanFactory;
227230
}
228231

229-
@Override
230-
public void setResourceLoader(ResourceLoader resourceLoader) {
231-
this.resourceLoader = resourceLoader;
232-
}
233232
}
234233

235234
/**

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
"name": "mybatis.configuration.default-enum-type-handler",
1414
"description": "A default TypeHandler class for Enum.",
1515
"type": "java.lang.Class<? extends org.apache.ibatis.type.TypeHandler>"
16+
},
17+
{
18+
"defaultValue": false,
19+
"name": "mybatis.lazy-initialization",
20+
"description": "Set whether enable lazy initialization for mapper bean.",
21+
"type": "java.lang.Boolean"
1622
}
1723
]
1824
}

mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,15 @@ public class CityDao {
297297
For detail see the <a href="http://www.mybatis.org/mybatis-3/configuration.html#properties">MyBatis reference page</a>
298298
</td>
299299
</tr>
300+
<tr>
301+
<td>
302+
<code>lazy-initialization</code>
303+
</td>
304+
<td>
305+
Whether enable lazy initialization of mapper bean. Set <code>true</code> to enable lazy initialization.
306+
This feature requires to use together with mybatis-spring 2.0.2+. (Available since 2.1.0)
307+
</td>
308+
</tr>
300309
<tr>
301310
<td>
302311
<code>configuration</code>

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ void testProperties() throws IOException {
4242
.parse(new FileSystemResource("src/main/resources/META-INF/additional-spring-configuration-metadata.json")
4343
.getInputStream());
4444

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

47-
assertThat(properties.size()).isEqualTo(2);
47+
assertThat(properties.size()).isEqualTo(3);
4848

4949
// assert for default-scripting-language
5050
{
51-
Map<String, String> element = properties.get(0);
51+
Map<String, Object> element = properties.get(0);
5252
assertThat(element.get("sourceType")).isEqualTo("org.apache.ibatis.session.Configuration");
5353
assertThat(element.get("defaultValue")).isEqualTo("org.apache.ibatis.scripting.xmltags.XMLLanguageDriver");
5454
assertThat(element.get("name")).isEqualTo("mybatis.configuration.default-scripting-language");
@@ -57,13 +57,21 @@ void testProperties() throws IOException {
5757

5858
// assert for default-enum-type-handler
5959
{
60-
Map<String, String> element = properties.get(1);
60+
Map<String, Object> element = properties.get(1);
6161
assertThat(element.get("sourceType")).isEqualTo("org.apache.ibatis.session.Configuration");
6262
assertThat(element.get("defaultValue")).isEqualTo("org.apache.ibatis.type.EnumTypeHandler");
6363
assertThat(element.get("name")).isEqualTo("mybatis.configuration.default-enum-type-handler");
6464
assertThat(element.get("type")).isEqualTo("java.lang.Class<? extends org.apache.ibatis.type.TypeHandler>");
6565
}
6666

67+
// assert for lazy-initialization
68+
{
69+
Map<String, Object> element = properties.get(2);
70+
assertThat(element.get("defaultValue")).isEqualTo(false);
71+
assertThat(element.get("name")).isEqualTo("mybatis.lazy-initialization");
72+
assertThat(element.get("type")).isEqualTo("java.lang.Boolean");
73+
}
74+
6775
}
6876

6977
}

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,51 @@ void testDefaultConfiguration() {
126126
MybatisScanMapperConfiguration.class, MybatisAutoConfiguration.class,
127127
PropertyPlaceholderAutoConfiguration.class);
128128
this.context.refresh();
129+
SqlSessionFactory sqlSessionFactory = this.context.getBean(SqlSessionFactory.class);
130+
assertThat(sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers()).hasSize(1);
129131
assertThat(this.context.getBeanNamesForType(SqlSessionFactory.class)).hasSize(1);
130132
assertThat(this.context.getBeanNamesForType(SqlSessionTemplate.class)).hasSize(1);
131133
assertThat(this.context.getBeanNamesForType(CityMapper.class)).hasSize(1);
132134
assertThat(this.context.getBean(SqlSessionTemplate.class).getExecutorType()).isEqualTo(ExecutorType.SIMPLE);
133135
assertThat(this.context.getBean(SqlSessionFactory.class).getConfiguration().isMapUnderscoreToCamelCase()).isFalse();
134136
}
135137

138+
@Test
139+
void testScanWithLazy() {
140+
TestPropertyValues.of("mybatis.lazy-initialization:true").applyTo(this.context);
141+
this.context.register(EmbeddedDataSourceConfiguration.class,
142+
MybatisScanMapperConfiguration.class,
143+
MybatisAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
144+
this.context.refresh();
145+
SqlSessionFactory sqlSessionFactory = this.context.getBean(SqlSessionFactory.class);
146+
assertThat(sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers()).hasSize(0);
147+
assertThat(this.context.getBeanNamesForType(SqlSessionFactory.class)).hasSize(1);
148+
assertThat(this.context.getBeanNamesForType(SqlSessionTemplate.class)).hasSize(1);
149+
assertThat(this.context.getBeanNamesForType(CityMapper.class)).hasSize(1);
150+
assertThat(this.context.getBean(SqlSessionTemplate.class).getExecutorType()).isEqualTo(ExecutorType.SIMPLE);
151+
assertThat(this.context.getBean(SqlSessionFactory.class).getConfiguration().isMapUnderscoreToCamelCase()).isFalse();
152+
this.context.getBean(CityMapper.class);
153+
assertThat(sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers()).hasSize(1);
154+
}
155+
156+
@Test
157+
void testAutoScanWithLazy() {
158+
TestPropertyValues.of("mybatis.lazy-initialization:true").applyTo(this.context);
159+
this.context.register(EmbeddedDataSourceConfiguration.class,
160+
MybatisBootMapperScanAutoConfiguration.class,
161+
MybatisAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
162+
this.context.refresh();
163+
SqlSessionFactory sqlSessionFactory = this.context.getBean(SqlSessionFactory.class);
164+
assertThat(sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers()).hasSize(0);
165+
assertThat(this.context.getBeanNamesForType(SqlSessionFactory.class)).hasSize(1);
166+
assertThat(this.context.getBeanNamesForType(SqlSessionTemplate.class)).hasSize(1);
167+
assertThat(this.context.getBeanNamesForType(CityMapper.class)).hasSize(1);
168+
assertThat(this.context.getBean(SqlSessionTemplate.class).getExecutorType()).isEqualTo(ExecutorType.SIMPLE);
169+
assertThat(this.context.getBean(SqlSessionFactory.class).getConfiguration().isMapUnderscoreToCamelCase()).isFalse();
170+
this.context.getBean(CityMapper.class);
171+
assertThat(sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers()).hasSize(1);
172+
}
173+
136174
@Test
137175
void testWithConfigLocation() {
138176
TestPropertyValues.of("mybatis.config-location:mybatis-config.xml").applyTo(this.context);
@@ -227,6 +265,8 @@ void testDefaultBootConfiguration() {
227265
MybatisAutoConfiguration.class,
228266
PropertyPlaceholderAutoConfiguration.class);
229267
this.context.refresh();
268+
SqlSessionFactory sqlSessionFactory = this.context.getBean(SqlSessionFactory.class);
269+
assertThat(sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers()).hasSize(1);
230270
assertThat(this.context.getBeanNamesForType(SqlSessionFactory.class)).hasSize(1);
231271
assertThat(this.context.getBeanNamesForType(SqlSessionTemplate.class)).hasSize(1);
232272
assertThat(this.context.getBeanNamesForType(CityMapper.class)).hasSize(1);
@@ -590,7 +630,7 @@ DataSource dataSourceSlave() {
590630

591631
@Configuration
592632
@EnableAutoConfiguration
593-
@MapperScan("org.mybatis.spring.boot.autoconfigure.mapper")
633+
@MapperScan(basePackages = "org.mybatis.spring.boot.autoconfigure.mapper", lazyInitialization = "${mybatis.lazy-initialization:false}")
594634
static class MybatisScanMapperConfiguration {
595635
}
596636

pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868

6969
<properties>
7070
<mybatis.version>3.5.1</mybatis.version>
71-
<mybatis-spring.version>2.0.1</mybatis-spring.version>
71+
<mybatis-spring.version>2.0.2-SNAPSHOT</mybatis-spring.version>
7272
<spring-boot.version>2.1.4.RELEASE</spring-boot.version>
7373
</properties>
7474

@@ -123,6 +123,11 @@
123123
</dependencies>
124124

125125
<repositories>
126+
<repository>
127+
<id>sonatype-oss-snapshots</id>
128+
<name>Sonatype OSS Snapshots Repository</name>
129+
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
130+
</repository>
126131
<repository>
127132
<id>spring-milestone</id>
128133
<name>Spring Milestone</name>

0 commit comments

Comments
 (0)