Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use declared class's package as base package if not present base packages on @MapperScan #438

Merged
merged 5 commits into from
Dec 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/main/java/org/mybatis/spring/annotation/MapperScan.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
/**
* Use this annotation to register MyBatis mapper interfaces when using Java Config. It performs when same work as
* {@link MapperScannerConfigurer} via {@link MapperScannerRegistrar}.
*
* <p>Either {@link #basePackageClasses} or {@link #basePackages} (or its alias
kazuki43zoo marked this conversation as resolved.
Show resolved Hide resolved
* {@link #value}) may be specified to define specific packages to scan.
* Since 2.0.4, If specific packages are not defined, scanning will occur from
* the package of the class that declares this annotation.
*
* <p>
* Configuration example:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
AnnotationAttributes mapperScanAttrs = AnnotationAttributes
.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
if (mapperScanAttrs != null) {
registerBeanDefinitions(mapperScanAttrs, registry, generateBaseBeanName(importingClassMetadata, 0));
registerBeanDefinitions(importingClassMetadata, mapperScanAttrs, registry, generateBaseBeanName(importingClassMetadata, 0));
}
}

void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry, String beanName) {
void registerBeanDefinitions(AnnotationMetadata annoMeta, AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry, String beanName) {

BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
builder.addPropertyValue("processPropertyPlaceHolders", true);
Expand Down Expand Up @@ -119,6 +119,10 @@ void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegis
basePackages.addAll(Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName)
.collect(Collectors.toList()));

if (basePackages.isEmpty()) {
basePackages.add(getDefaultBasePackage(annoMeta));
}

String lazyInitialization = annoAttrs.getString("lazyInitialization");
if (StringUtils.hasText(lazyInitialization)) {
builder.addPropertyValue("lazyInitialization", lazyInitialization);
Expand All @@ -134,6 +138,10 @@ private static String generateBaseBeanName(AnnotationMetadata importingClassMeta
return importingClassMetadata.getClassName() + "#" + MapperScannerRegistrar.class.getSimpleName() + "#" + index;
}

private static String getDefaultBasePackage(AnnotationMetadata importingClassMetadata) {
return ClassUtils.getPackageName(importingClassMetadata.getClassName());
}

/**
* A {@link MapperScannerRegistrar} for {@link MapperScans}.
*
Expand All @@ -150,7 +158,7 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
if (mapperScansAttrs != null) {
AnnotationAttributes[] annotations = mapperScansAttrs.getAnnotationArray("value");
for (int i = 0; i < annotations.length; i++) {
registerBeanDefinitions(annotations[i], registry, generateBaseBeanName(importingClassMetadata, i));
registerBeanDefinitions(importingClassMetadata, annotations[i], registry, generateBaseBeanName(importingClassMetadata, i));
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/site/es/xdoc/mappers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,11 @@ public class AppConfig {
Tambien puedes indicar una <code>SqlSessionFactory</code> o un <code>SqlSessionTemplate</code> específicos
mediante las propiedades <code>sqlSessionFactory</code> y <code>sqlSessionTemplate</code>.
</p>


<p>
<span class="label important">NOTE</span> Since 2.0.4, If <code>basePackageClasses</code> or <code>basePackages</code> are not defined, scanning will occur from the package of the class that declares this annotation.
</p>

<h4>MapperScannerConfigurer</h4>

<p>
Expand Down
6 changes: 5 additions & 1 deletion src/site/ja/xdoc/mappers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,11 @@ public class AppConfig {
このアノテーションは前章で説明した <code>&lt;mybatis:scan/&gt;</code> と全く同じ要領で Mapper の検出を行います。
引数 <code>markerInterface</code>, <code>annotationClass</code> を使えば検出対象のマーカーインターフェイスとアノテーションを指定することもできますし、<code>sqlSessionFactory</code>, <code>sqlSessionTemplate</code> で <code>SqlSessionFactory</code> や <code>SqlSessionTemplate</code> を指定することができます。
</p>


<p>
<span class="label important">NOTE</span> 2.0.4以降では、 <code>basePackageClasses</code> もしくは <code>basePackages</code> が指定されていない場合、このアノテーションが定義されているクラスのパッケージを基準にスキャンします。
</p>

<h4>MapperScannerConfigurer</h4>

<p>
Expand Down
6 changes: 5 additions & 1 deletion src/site/ko/xdoc/mappers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,11 @@ public class AppConfig {
<code>markerInterface</code> 와 <code>annotationClass</code> 프로퍼티를 사용해서 마커 인터페이스와 애노테이션 클래스를 명시하게 한다.
<code>sqlSessionFactory</code> 와 <code>sqlSessionTemplate</code> 프로퍼티를 사용해서
<code>SqlSessionFactory</code> 나 <code>SqlSessionTemplate</code>을 제공할 수도 있다. </p>


<p>
<span class="label important">NOTE</span> Since 2.0.4, If <code>basePackageClasses</code> or <code>basePackages</code> are not defined, scanning will occur from the package of the class that declares this annotation.
</p>

<h4>MapperScannerConfigurer</h4>

<p><code>MapperScannerConfigurer</code>는 평범한 빈처럼 XML애플리케이션 컨텍스트에 포함된 <code>BeanDefinitionRegistryPostProcessor</code> 이다.
Expand Down
6 changes: 5 additions & 1 deletion src/site/xdoc/mappers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,11 @@ public class AppConfig {
You can also provide an specific <code>SqlSessionFactory</code> or <code>SqlSessionTemplate</code>
by using its properties <code>sqlSessionFactory</code> and <code>sqlSessionTemplate</code>.
</p>


<p>
<span class="label important">NOTE</span> Since 2.0.4, If <code>basePackageClasses</code> or <code>basePackages</code> are not defined, scanning will occur from the package of the class that declares this annotation.
kazuki43zoo marked this conversation as resolved.
Show resolved Hide resolved
</p>

<h4>MapperScannerConfigurer</h4>

<p>
Expand Down
4 changes: 4 additions & 0 deletions src/site/zh/xdoc/mappers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ public class AppConfig {
这个注解具有与之前见过的 <code>&lt;mybatis:scan/&gt;</code> 元素一样的工作方式。它也可以通过 <code>markerInterface</code> 和 <code>annotationClass</code> 属性设置标记接口或注解类。通过配置 <code>sqlSessionFactory</code> 和 <code>sqlSessionTemplate</code> 属性,你还能指定一个 <code>SqlSessionFactory</code> 或 <code>SqlSessionTemplate</code>。
</p>

<p>
<span class="label important">NOTE</span> Since 2.0.4, If <code>basePackageClasses</code> or <code>basePackages</code> are not defined, scanning will occur from the package of the class that declares this annotation.
</p>

<h4>MapperScannerConfigurer</h4>

<p>
Expand Down
42 changes: 42 additions & 0 deletions src/test/java/org/mybatis/spring/annotation/MapperScanTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@
import org.junit.jupiter.api.Test;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.mapper.ds1.AppConfigWithDefaultMapperScanAndRepeat;
import org.mybatis.spring.annotation.mapper.ds1.AppConfigWithDefaultMapperScans;
import org.mybatis.spring.annotation.mapper.ds1.Ds1Mapper;
import org.mybatis.spring.mapper.AnnotatedMapper;
import org.mybatis.spring.mapper.AppConfigWithDefaultPackageScan;
import org.mybatis.spring.mapper.MapperInterface;
import org.mybatis.spring.mapper.MapperSubinterface;
import org.mybatis.spring.mapper.child.MapperChildInterface;
Expand Down Expand Up @@ -90,6 +93,19 @@ void assertNoMapperClass() {
}
}

kazuki43zoo marked this conversation as resolved.
Show resolved Hide resolved
@Test
void testDefaultMapperScan() {
applicationContext.register(AppConfigWithDefaultPackageScan.class);

startContext();

// all interfaces with methods should be loaded
applicationContext.getBean("mapperInterface");
applicationContext.getBean("mapperSubinterface");
applicationContext.getBean("mapperChildInterface");
applicationContext.getBean("annotatedMapper");
}

@Test
void testInterfaceScan() {
applicationContext.register(AppConfigWithPackageScan.class);
Expand Down Expand Up @@ -275,6 +291,32 @@ void testScanWithMapperScans() {
applicationContext.getBean("ds2Mapper");
}

@Test
void testScanWithDefaultMapperScanAndRepeat() {
applicationContext.register(AppConfigWithDefaultMapperScanAndRepeat.class);

startContext();

SqlSessionFactory sqlSessionFactory = applicationContext.getBean(SqlSessionFactory.class);
assertEquals(2, sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers().size());

applicationContext.getBean("ds1Mapper");
applicationContext.getBean("ds2Mapper");
}

@Test
void testScanWithDefaultMapperScans() {
applicationContext.register(AppConfigWithDefaultMapperScans.class);

startContext();

SqlSessionFactory sqlSessionFactory = applicationContext.getBean(SqlSessionFactory.class);
assertEquals(2, sqlSessionFactory.getConfiguration().getMapperRegistry().getMappers().size());

applicationContext.getBean("ds1Mapper");
applicationContext.getBean("ds2Mapper");
}

@Test
void testLazyScanWithPropertySourcesPlaceholderConfigurer() {
applicationContext.register(LazyConfigWithPropertySourcesPlaceholderConfigurer.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.mybatis.spring.annotation.mapper.ds1;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan
@MapperScan("org.mybatis.spring.annotation.mapper.ds2")
public class AppConfigWithDefaultMapperScanAndRepeat {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.mybatis.spring.annotation.mapper.ds1;

import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.annotation.MapperScans;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScans({
@MapperScan,
@MapperScan("org.mybatis.spring.annotation.mapper.ds2")
})
public class AppConfigWithDefaultMapperScans {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.mybatis.spring.mapper;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan
public class AppConfigWithDefaultPackageScan {

}