1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.spring.annotation;
17
18 import java.lang.annotation.Annotation;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.List;
22 import java.util.stream.Collectors;
23
24 import org.mybatis.spring.mapper.ClassPathMapperScanner;
25 import org.mybatis.spring.mapper.MapperFactoryBean;
26 import org.mybatis.spring.mapper.MapperScannerConfigurer;
27 import org.springframework.beans.BeanUtils;
28 import org.springframework.beans.factory.config.BeanDefinition;
29 import org.springframework.beans.factory.support.AbstractBeanDefinition;
30 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
31 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
32 import org.springframework.beans.factory.support.BeanNameGenerator;
33 import org.springframework.context.ResourceLoaderAware;
34 import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
35 import org.springframework.core.annotation.AnnotationAttributes;
36 import org.springframework.core.io.ResourceLoader;
37 import org.springframework.core.type.AnnotationMetadata;
38 import org.springframework.util.ClassUtils;
39 import org.springframework.util.StringUtils;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
56
57
58
59
60
61
62 @Override
63 @Deprecated
64 public void setResourceLoader(ResourceLoader resourceLoader) {
65
66 }
67
68
69
70
71 @Override
72 public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
73 AnnotationAttributes mapperScanAttrs = AnnotationAttributes
74 .fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
75 if (mapperScanAttrs != null) {
76 registerBeanDefinitions(importingClassMetadata, mapperScanAttrs, registry,
77 generateBaseBeanName(importingClassMetadata, 0));
78 }
79 }
80
81 void registerBeanDefinitions(AnnotationMetadata annoMeta, AnnotationAttributes annoAttrs,
82 BeanDefinitionRegistry registry, String beanName) {
83
84 BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
85 builder.addPropertyValue("processPropertyPlaceHolders", true);
86
87 Class<? extends Annotation> annotationClass = annoAttrs.getClass("annotationClass");
88 if (!Annotation.class.equals(annotationClass)) {
89 builder.addPropertyValue("annotationClass", annotationClass);
90 }
91
92 Class<?> markerInterface = annoAttrs.getClass("markerInterface");
93 if (!Class.class.equals(markerInterface)) {
94 builder.addPropertyValue("markerInterface", markerInterface);
95 }
96
97 Class<? extends BeanNameGenerator> generatorClass = annoAttrs.getClass("nameGenerator");
98 if (!BeanNameGenerator.class.equals(generatorClass)) {
99 builder.addPropertyValue("nameGenerator", BeanUtils.instantiateClass(generatorClass));
100 }
101
102 Class<? extends MapperFactoryBean> mapperFactoryBeanClass = annoAttrs.getClass("factoryBean");
103 if (!MapperFactoryBean.class.equals(mapperFactoryBeanClass)) {
104 builder.addPropertyValue("mapperFactoryBeanClass", mapperFactoryBeanClass);
105 }
106
107 String sqlSessionTemplateRef = annoAttrs.getString("sqlSessionTemplateRef");
108 if (StringUtils.hasText(sqlSessionTemplateRef)) {
109 builder.addPropertyValue("sqlSessionTemplateBeanName", annoAttrs.getString("sqlSessionTemplateRef"));
110 }
111
112 String sqlSessionFactoryRef = annoAttrs.getString("sqlSessionFactoryRef");
113 if (StringUtils.hasText(sqlSessionFactoryRef)) {
114 builder.addPropertyValue("sqlSessionFactoryBeanName", annoAttrs.getString("sqlSessionFactoryRef"));
115 }
116
117 List<String> basePackages = new ArrayList<>();
118
119 basePackages.addAll(Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText)
120 .collect(Collectors.toList()));
121
122 basePackages.addAll(Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName)
123 .collect(Collectors.toList()));
124
125 if (basePackages.isEmpty()) {
126 basePackages.add(getDefaultBasePackage(annoMeta));
127 }
128
129 String lazyInitialization = annoAttrs.getString("lazyInitialization");
130 if (StringUtils.hasText(lazyInitialization)) {
131 builder.addPropertyValue("lazyInitialization", lazyInitialization);
132 }
133
134 String defaultScope = annoAttrs.getString("defaultScope");
135 if (!AbstractBeanDefinition.SCOPE_DEFAULT.equals(defaultScope)) {
136 builder.addPropertyValue("defaultScope", defaultScope);
137 }
138
139 builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(basePackages));
140
141
142 builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
143
144 registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
145
146 }
147
148 private static String generateBaseBeanName(AnnotationMetadata importingClassMetadata, int index) {
149 return importingClassMetadata.getClassName() + "#" + MapperScannerRegistrar.class.getSimpleName() + "#" + index;
150 }
151
152 private static String getDefaultBasePackage(AnnotationMetadata importingClassMetadata) {
153 return ClassUtils.getPackageName(importingClassMetadata.getClassName());
154 }
155
156
157
158
159
160
161 static class RepeatingRegistrar extends MapperScannerRegistrar {
162
163
164
165 @Override
166 public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
167 AnnotationAttributes mapperScansAttrs = AnnotationAttributes
168 .fromMap(importingClassMetadata.getAnnotationAttributes(MapperScans.class.getName()));
169 if (mapperScansAttrs != null) {
170 AnnotationAttributes[] annotations = mapperScansAttrs.getAnnotationArray("value");
171 for (int i = 0; i < annotations.length; i++) {
172 registerBeanDefinitions(importingClassMetadata, annotations[i], registry,
173 generateBaseBeanName(importingClassMetadata, i));
174 }
175 }
176 }
177 }
178
179 }