Skip to content

Commit 7f23b51

Browse files
authored
Merge pull request mybatis#352 from kazuki43zoo/allow-custom-mapper-factory-bean-class-on-namespace
Allow to specify custom MapperFactoryBean class on xml based bean definition
2 parents b5ce018 + 65639fe commit 7f23b51

File tree

8 files changed

+113
-4
lines changed

8 files changed

+113
-4
lines changed

src/main/java/org/mybatis/spring/config/MapperScannerBeanDefinitionParser.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2010-2016 the original author or authors.
2+
* Copyright 2010-2019 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.
@@ -49,6 +49,7 @@ public class MapperScannerBeanDefinitionParser implements BeanDefinitionParser {
4949
private static final String ATTRIBUTE_NAME_GENERATOR = "name-generator";
5050
private static final String ATTRIBUTE_TEMPLATE_REF = "template-ref";
5151
private static final String ATTRIBUTE_FACTORY_REF = "factory-ref";
52+
private static final String ATTRIBUTE_MAPPER_FACTORY_BEAN_CLASS = "mapper-factory-bean-class";
5253

5354
/**
5455
* {@inheritDoc}
@@ -77,6 +78,13 @@ public synchronized BeanDefinition parse(Element element, ParserContext parserCo
7778
BeanNameGenerator nameGenerator = BeanUtils.instantiateClass(nameGeneratorClass, BeanNameGenerator.class);
7879
scanner.setBeanNameGenerator(nameGenerator);
7980
}
81+
String mapperFactoryBeanClassName = element.getAttribute(ATTRIBUTE_MAPPER_FACTORY_BEAN_CLASS);
82+
if (StringUtils.hasText(mapperFactoryBeanClassName)) {
83+
@SuppressWarnings("unchecked")
84+
Class<? extends MapperFactoryBean> mapperFactoryBeanClass =
85+
(Class<? extends MapperFactoryBean>)classLoader.loadClass(mapperFactoryBeanClassName);
86+
scanner.setMapperFactoryBeanClass(mapperFactoryBeanClass);
87+
}
8088
} catch (Exception ex) {
8189
readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
8290
}

src/main/java/org/mybatis/spring/config/mybatis-spring.xsd

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
4-
Copyright 2010-2018 the original author or authors.
4+
Copyright 2010-2019 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.
@@ -105,6 +105,21 @@
105105
</xsd:appinfo>
106106
</xsd:annotation>
107107
</xsd:attribute>
108+
<xsd:attribute name="mapper-factory-bean-class" type="xsd:string">
109+
<xsd:annotation>
110+
<xsd:documentation>
111+
<![CDATA[
112+
The fully-qualified class name of the MapperFactoryBean to return a mybatis proxy as spring bean. (Since 2.0.1)
113+
]]>
114+
</xsd:documentation>
115+
<xsd:appinfo>
116+
<tool:annotation>
117+
<tool:expected-type type="java.lang.Class" />
118+
<tool:assignable-to type="org.mybatis.spring.mapper.MapperFactoryBean" />
119+
</tool:annotation>
120+
</xsd:appinfo>
121+
</xsd:annotation>
122+
</xsd:attribute>
108123
</xsd:complexType>
109124
</xsd:element>
110125
</xsd:schema>

src/main/java/org/mybatis/spring/mapper/MapperScannerConfigurer.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2010-2018 the original author or authors.
2+
* Copyright 2010-2019 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.
@@ -108,6 +108,8 @@ public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProces
108108

109109
private Class<?> markerInterface;
110110

111+
private Class<? extends MapperFactoryBean> mapperFactoryBeanClass;
112+
111113
private ApplicationContext applicationContext;
112114

113115
private String beanName;
@@ -241,6 +243,16 @@ public void setProcessPropertyPlaceHolders(boolean processPropertyPlaceHolders)
241243
this.processPropertyPlaceHolders = processPropertyPlaceHolders;
242244
}
243245

246+
/**
247+
* The class of the {@link MapperFactoryBean} to return a mybatis proxy as spring bean.
248+
*
249+
* @param mapperFactoryBeanClass The class of the MapperFactoryBean
250+
* @since 2.0.1
251+
*/
252+
public void setMapperFactoryBeanClass(Class<? extends MapperFactoryBean> mapperFactoryBeanClass) {
253+
this.mapperFactoryBeanClass = mapperFactoryBeanClass;
254+
}
255+
244256
/**
245257
* {@inheritDoc}
246258
*/
@@ -314,6 +326,7 @@ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
314326
scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
315327
scanner.setResourceLoader(this.applicationContext);
316328
scanner.setBeanNameGenerator(this.nameGenerator);
329+
scanner.setMapperFactoryBeanClass(this.mapperFactoryBeanClass);
317330
scanner.registerFilters();
318331
scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
319332
}

src/test/java/org/mybatis/spring/annotation/MapperScanTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ void testMarkerInterfaceAndAnnotationScan() {
166166

167167
@Test
168168
void testCustomMapperFactoryBean() {
169+
DummyMapperFactoryBean.clear();
169170
applicationContext.register(AppConfigWithCustomMapperFactoryBean.class);
170171

171172
startContext();

src/test/java/org/mybatis/spring/config/NamespaceTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.mybatis.spring.config;
1717

18+
import static org.junit.jupiter.api.Assertions.assertTrue;
1819
import static org.junit.jupiter.api.Assertions.fail;
1920

2021
import org.junit.jupiter.api.AfterEach;
@@ -25,6 +26,7 @@
2526
import org.mybatis.spring.mapper.MapperInterface;
2627
import org.mybatis.spring.mapper.MapperSubinterface;
2728
import org.mybatis.spring.mapper.child.MapperChildInterface;
29+
import org.mybatis.spring.type.DummyMapperFactoryBean;
2830
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
2931
import org.springframework.beans.factory.config.BeanDefinition;
3032
import org.springframework.beans.factory.config.ConstructorArgumentValues;
@@ -170,6 +172,24 @@ void testScanWithExplicitSqlSessionTemplate() {
170172
applicationContext.getBean("annotatedMapper");
171173
}
172174

175+
@Test
176+
void testScanWithMapperFactoryBeanClass() {
177+
DummyMapperFactoryBean.clear();
178+
applicationContext = new ClassPathXmlApplicationContext(
179+
new String[] { "org/mybatis/spring/config/mapper-factory-bean-class.xml" }
180+
, setupSqlSessionTemplate());
181+
182+
startContext();
183+
184+
// all interfaces with methods should be loaded
185+
applicationContext.getBean("mapperInterface");
186+
applicationContext.getBean("mapperSubinterface");
187+
applicationContext.getBean("mapperChildInterface");
188+
applicationContext.getBean("annotatedMapper");
189+
190+
assertTrue(DummyMapperFactoryBean.getMapperCount() > 0);
191+
}
192+
173193
private GenericApplicationContext setupSqlSessionTemplate() {
174194

175195
GenericApplicationContext genericApplicationContext = setupSqlSessionFactory();
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Copyright 2010-2019 the original author or authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
-->
19+
<beans xmlns="http://www.springframework.org/schema/beans"
20+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
21+
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
22+
xsi:schemaLocation="
23+
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
24+
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">
25+
26+
<mybatis:scan base-package="org.mybatis.spring.mapper"
27+
mapper-factory-bean-class="org.mybatis.spring.type.DummyMapperFactoryBean"/>
28+
</beans>

src/test/java/org/mybatis/spring/mapper/MapperScannerConfigurerTest.java

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

1818
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.junit.jupiter.api.Assertions.assertTrue;
1920
import static org.junit.jupiter.api.Assertions.fail;
2021

2122
import java.util.Properties;
@@ -28,6 +29,7 @@
2829
import org.mybatis.spring.SqlSessionFactoryBean;
2930
import org.mybatis.spring.SqlSessionTemplate;
3031
import org.mybatis.spring.mapper.child.MapperChildInterface;
32+
import org.mybatis.spring.type.DummyMapperFactoryBean;
3133
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
3234
import org.springframework.beans.factory.config.BeanDefinition;
3335
import org.springframework.beans.factory.config.ConstructorArgumentValues;
@@ -254,6 +256,23 @@ void testScanWithPropertyPlaceholders() {
254256
assertThat(sessionFactory.getConfiguration().getDefaultExecutorType()).isSameAs(ExecutorType.REUSE);
255257
}
256258

259+
@Test
260+
void testScanWithMapperFactoryBeanClass() {
261+
DummyMapperFactoryBean.clear();
262+
applicationContext.getBeanDefinition("mapperScanner").getPropertyValues().add(
263+
"mapperFactoryBeanClass", DummyMapperFactoryBean.class);
264+
265+
startContext();
266+
267+
applicationContext.getBean("mapperInterface");
268+
applicationContext.getBean("mapperSubinterface");
269+
applicationContext.getBean("mapperChildInterface");
270+
applicationContext.getBean("annotatedMapper");
271+
272+
assertTrue(DummyMapperFactoryBean.getMapperCount() > 0);
273+
}
274+
275+
257276
private void setupSqlSessionFactory(String name) {
258277
GenericBeanDefinition definition = new GenericBeanDefinition();
259278
definition.setBeanClass(SqlSessionFactoryBean.class);

src/test/java/org/mybatis/spring/type/DummyMapperFactoryBean.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2010-2017 the original author or authors.
2+
* Copyright 2010-2019 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.
@@ -77,4 +77,9 @@ private SqlSessionFactory getCustomSessionFactoryForClass() {
7777
public static int getMapperCount(){
7878
return mapperInstanceCount.get();
7979
}
80+
81+
public static void clear() {
82+
mapperInstanceCount.set(0);
83+
}
84+
8085
}

0 commit comments

Comments
 (0)