|
1 | 1 | package tk.mybatis.spring.mapper;
|
2 | 2 |
|
3 |
| -import java.io.IOException; |
4 |
| -import java.lang.annotation.Annotation; |
5 |
| -import java.util.Arrays; |
6 |
| -import java.util.Set; |
7 |
| - |
8 |
| -import org.apache.ibatis.session.SqlSessionFactory; |
9 |
| -import org.mybatis.spring.SqlSessionTemplate; |
10 |
| -import org.mybatis.spring.mapper.*; |
11 |
| -import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; |
12 |
| -import org.springframework.beans.factory.config.BeanDefinition; |
13 | 3 | import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
14 |
| -import org.springframework.beans.factory.config.RuntimeBeanReference; |
15 |
| -import org.springframework.beans.factory.support.AbstractBeanDefinition; |
16 | 4 | import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
17 | 5 | import org.springframework.beans.factory.support.GenericBeanDefinition;
|
18 |
| -import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; |
19 |
| -import org.springframework.core.type.classreading.MetadataReader; |
20 |
| -import org.springframework.core.type.classreading.MetadataReaderFactory; |
21 |
| -import org.springframework.core.type.filter.AnnotationTypeFilter; |
22 |
| -import org.springframework.core.type.filter.AssignableTypeFilter; |
23 |
| -import org.springframework.core.type.filter.TypeFilter; |
24 |
| -import org.springframework.util.StringUtils; |
25 | 6 | import tk.mybatis.mapper.mapperhelper.MapperHelper;
|
26 | 7 |
|
| 8 | +import java.util.Set; |
| 9 | + |
27 | 10 | /**
|
28 |
| - * A {@link ClassPathBeanDefinitionScanner} that registers Mappers by |
29 |
| - * {@code basePackage}, {@code annotationClass}, or {@code markerInterface}. If |
30 |
| - * an {@code annotationClass} and/or {@code markerInterface} is specified, only |
31 |
| - * the specified types will be searched (searching for all interfaces will be |
32 |
| - * disabled). |
33 |
| - * <p> |
34 |
| - * This functionality was previously a private class of |
35 |
| - * {@link org.mybatis.spring.mapper.MapperScannerConfigurer}, but was broken out in version 1.2.0. |
| 11 | + * 重写ClassPathMapperScanner |
36 | 12 | *
|
37 |
| - * @author Hunter Presnall |
38 |
| - * @author Eduardo Macarron |
| 13 | + * 主要在doScan方法中注入mapperHelper和tk.xxx.MapperFactoryBean |
39 | 14 | *
|
40 |
| - * @see MapperFactoryBean |
41 |
| - * @since 1.2.0 |
42 |
| - * @version $Id$ |
| 15 | + * @author liuzh |
43 | 16 | */
|
44 |
| -public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner { |
45 |
| - |
46 |
| - private boolean addToConfig = true; |
47 |
| - |
48 |
| - private SqlSessionFactory sqlSessionFactory; |
49 |
| - |
50 |
| - private SqlSessionTemplate sqlSessionTemplate; |
51 |
| - |
52 |
| - private String sqlSessionTemplateBeanName; |
53 |
| - |
54 |
| - private String sqlSessionFactoryBeanName; |
55 |
| - |
56 |
| - private Class<? extends Annotation> annotationClass; |
57 |
| - |
58 |
| - private Class<?> markerInterface; |
| 17 | +public class ClassPathMapperScanner extends org.mybatis.spring.mapper.ClassPathMapperScanner { |
59 | 18 |
|
60 | 19 | private MapperHelper mapperHelper;
|
61 | 20 |
|
62 |
| - private MapperFactoryBean mapperFactoryBean = new MapperFactoryBean(); |
63 |
| - |
64 | 21 | public ClassPathMapperScanner(BeanDefinitionRegistry registry) {
|
65 |
| - super(registry, false); |
66 |
| - } |
67 |
| - |
68 |
| - public void setAddToConfig(boolean addToConfig) { |
69 |
| - this.addToConfig = addToConfig; |
70 |
| - } |
71 |
| - |
72 |
| - public void setAnnotationClass(Class<? extends Annotation> annotationClass) { |
73 |
| - this.annotationClass = annotationClass; |
74 |
| - } |
75 |
| - |
76 |
| - public void setMarkerInterface(Class<?> markerInterface) { |
77 |
| - this.markerInterface = markerInterface; |
78 |
| - } |
79 |
| - |
80 |
| - public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { |
81 |
| - this.sqlSessionFactory = sqlSessionFactory; |
82 |
| - } |
83 |
| - |
84 |
| - public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) { |
85 |
| - this.sqlSessionTemplate = sqlSessionTemplate; |
86 |
| - } |
87 |
| - |
88 |
| - public void setSqlSessionTemplateBeanName(String sqlSessionTemplateBeanName) { |
89 |
| - this.sqlSessionTemplateBeanName = sqlSessionTemplateBeanName; |
90 |
| - } |
91 |
| - |
92 |
| - public void setSqlSessionFactoryBeanName(String sqlSessionFactoryBeanName) { |
93 |
| - this.sqlSessionFactoryBeanName = sqlSessionFactoryBeanName; |
| 22 | + super(registry); |
94 | 23 | }
|
95 | 24 |
|
96 | 25 | public void setMapperHelper(MapperHelper mapperHelper) {
|
97 | 26 | this.mapperHelper = mapperHelper;
|
98 | 27 | }
|
99 | 28 |
|
100 |
| - public void setMapperFactoryBean(MapperFactoryBean mapperFactoryBean) { |
101 |
| - this.mapperFactoryBean = (mapperFactoryBean != null ? mapperFactoryBean : new MapperFactoryBean()); |
102 |
| - } |
103 |
| - |
104 |
| - |
105 |
| - /** |
106 |
| - * Configures parent scanner to search for the right interfaces. It can search |
107 |
| - * for all interfaces or just for those that extends a markerInterface or/and |
108 |
| - * those annotated with the annotationClass |
109 |
| - */ |
110 |
| - public void registerFilters() { |
111 |
| - boolean acceptAllInterfaces = true; |
112 |
| - |
113 |
| - // if specified, use the given annotation and / or marker interface |
114 |
| - if (this.annotationClass != null) { |
115 |
| - addIncludeFilter(new AnnotationTypeFilter(this.annotationClass)); |
116 |
| - acceptAllInterfaces = false; |
117 |
| - } |
118 |
| - |
119 |
| - // override AssignableTypeFilter to ignore matches on the actual marker interface |
120 |
| - if (this.markerInterface != null) { |
121 |
| - addIncludeFilter(new AssignableTypeFilter(this.markerInterface) { |
122 |
| - @Override |
123 |
| - protected boolean matchClassName(String className) { |
124 |
| - return false; |
125 |
| - } |
126 |
| - }); |
127 |
| - acceptAllInterfaces = false; |
128 |
| - } |
129 |
| - |
130 |
| - if (acceptAllInterfaces) { |
131 |
| - // default include filter that accepts all classes |
132 |
| - addIncludeFilter(new TypeFilter() { |
133 |
| - @Override |
134 |
| - public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { |
135 |
| - return true; |
136 |
| - } |
137 |
| - }); |
138 |
| - } |
139 |
| - |
140 |
| - // exclude package-info.java |
141 |
| - addExcludeFilter(new TypeFilter() { |
142 |
| - @Override |
143 |
| - public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { |
144 |
| - String className = metadataReader.getClassMetadata().getClassName(); |
145 |
| - return className.endsWith("package-info"); |
146 |
| - } |
147 |
| - }); |
148 |
| - } |
149 |
| - |
150 |
| - /** |
151 |
| - * Calls the parent search that will search and register all the candidates. |
152 |
| - * Then the registered objects are post processed to set them as |
153 |
| - * MapperFactoryBeans |
154 |
| - */ |
155 | 29 | @Override
|
156 | 30 | public Set<BeanDefinitionHolder> doScan(String... basePackages) {
|
157 | 31 | Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
|
158 |
| - |
159 |
| - if (beanDefinitions.isEmpty()) { |
160 |
| - logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration."); |
161 |
| - } else { |
162 |
| - processBeanDefinitions(beanDefinitions); |
163 |
| - } |
164 |
| - |
165 |
| - return beanDefinitions; |
166 |
| - } |
167 |
| - |
168 |
| - private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) { |
| 32 | + //注入mapperHelper |
169 | 33 | GenericBeanDefinition definition;
|
170 | 34 | for (BeanDefinitionHolder holder : beanDefinitions) {
|
171 | 35 | definition = (GenericBeanDefinition) holder.getBeanDefinition();
|
172 |
| - |
173 |
| - if (logger.isDebugEnabled()) { |
174 |
| - logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() |
175 |
| - + "' and '" + definition.getBeanClassName() + "' mapperInterface"); |
176 |
| - } |
177 |
| - |
178 |
| - // the mapper interface is the original class of the bean |
179 |
| - // but, the actual class of the bean is MapperFactoryBean |
180 |
| - definition.getPropertyValues().add("mapperInterface", definition.getBeanClassName()); |
181 |
| - definition.setBeanClass(this.mapperFactoryBean.getClass()); |
182 |
| - |
183 | 36 | definition.getPropertyValues().add("mapperHelper", this.mapperHelper);
|
184 |
| - definition.getPropertyValues().add("addToConfig", this.addToConfig); |
185 |
| - |
186 |
| - boolean explicitFactoryUsed = false; |
187 |
| - if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) { |
188 |
| - definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName)); |
189 |
| - explicitFactoryUsed = true; |
190 |
| - } else if (this.sqlSessionFactory != null) { |
191 |
| - definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory); |
192 |
| - explicitFactoryUsed = true; |
193 |
| - } |
194 |
| - |
195 |
| - if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) { |
196 |
| - if (explicitFactoryUsed) { |
197 |
| - logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored."); |
198 |
| - } |
199 |
| - definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName)); |
200 |
| - explicitFactoryUsed = true; |
201 |
| - } else if (this.sqlSessionTemplate != null) { |
202 |
| - if (explicitFactoryUsed) { |
203 |
| - logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored."); |
204 |
| - } |
205 |
| - definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate); |
206 |
| - explicitFactoryUsed = true; |
207 |
| - } |
208 |
| - |
209 |
| - if (!explicitFactoryUsed) { |
210 |
| - if (logger.isDebugEnabled()) { |
211 |
| - logger.debug("Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'."); |
212 |
| - } |
213 |
| - definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); |
214 |
| - } |
215 |
| - } |
216 |
| - } |
217 |
| - |
218 |
| - /** |
219 |
| - * {@inheritDoc} |
220 |
| - */ |
221 |
| - @Override |
222 |
| - protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { |
223 |
| - return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent(); |
224 |
| - } |
225 |
| - |
226 |
| - /** |
227 |
| - * {@inheritDoc} |
228 |
| - */ |
229 |
| - @Override |
230 |
| - protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) { |
231 |
| - if (super.checkCandidate(beanName, beanDefinition)) { |
232 |
| - return true; |
233 |
| - } else { |
234 |
| - logger.warn("Skipping MapperFactoryBean with name '" + beanName |
235 |
| - + "' and '" + beanDefinition.getBeanClassName() + "' mapperInterface" |
236 |
| - + ". Bean already defined with the same name!"); |
237 |
| - return false; |
| 37 | + definition.setBeanClass(MapperFactoryBean.class); |
238 | 38 | }
|
| 39 | + return beanDefinitions; |
239 | 40 | }
|
240 |
| - |
241 | 41 | }
|
0 commit comments