1
1
/**
2
- * Copyright 2010-2019 the original author or authors.
2
+ * Copyright 2010-2020 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
15
15
*/
16
16
package org .mybatis .spring .mapper ;
17
17
18
+ import java .lang .annotation .Annotation ;
19
+ import java .util .Arrays ;
20
+ import java .util .Optional ;
21
+ import java .util .Set ;
22
+
18
23
import org .apache .ibatis .session .SqlSessionFactory ;
19
24
import org .mybatis .logging .Logger ;
20
25
import org .mybatis .logging .LoggerFactory ;
21
26
import org .mybatis .spring .SqlSessionTemplate ;
27
+ import org .springframework .aop .scope .ScopedProxyFactoryBean ;
28
+ import org .springframework .aop .scope .ScopedProxyUtils ;
22
29
import org .springframework .beans .factory .annotation .AnnotatedBeanDefinition ;
23
30
import org .springframework .beans .factory .config .BeanDefinition ;
24
31
import org .springframework .beans .factory .config .BeanDefinitionHolder ;
32
+ import org .springframework .beans .factory .config .ConfigurableBeanFactory ;
25
33
import org .springframework .beans .factory .config .RuntimeBeanReference ;
26
34
import org .springframework .beans .factory .support .AbstractBeanDefinition ;
27
35
import org .springframework .beans .factory .support .BeanDefinitionRegistry ;
28
- import org .springframework .beans .factory .support .GenericBeanDefinition ;
36
+ import org .springframework .beans .factory .support .RootBeanDefinition ;
29
37
import org .springframework .context .annotation .ClassPathBeanDefinitionScanner ;
30
38
import org .springframework .core .type .filter .AnnotationTypeFilter ;
31
39
import org .springframework .core .type .filter .AssignableTypeFilter ;
32
40
import org .springframework .util .StringUtils ;
33
41
34
- import java .lang .annotation .Annotation ;
35
- import java .util .Arrays ;
36
- import java .util .Set ;
37
-
38
42
/**
39
43
* A {@link ClassPathBeanDefinitionScanner} that registers Mappers by {@code basePackage}, {@code annotationClass}, or
40
44
* {@code markerInterface}. If an {@code annotationClass} and/or {@code markerInterface} is specified, only the
45
49
*
46
50
* @author Hunter Presnall
47
51
* @author Eduardo Macarron
48
- *
52
+ *
49
53
* @see MapperFactoryBean
50
54
* @since 1.2.0
51
55
*/
@@ -71,6 +75,8 @@ public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {
71
75
72
76
private Class <? extends MapperFactoryBean > mapperFactoryBeanClass = MapperFactoryBean .class ;
73
77
78
+ private String defaultScope ;
79
+
74
80
public ClassPathMapperScanner (BeanDefinitionRegistry registry ) {
75
81
super (registry , false );
76
82
}
@@ -136,6 +142,20 @@ public void setMapperFactoryBeanClass(Class<? extends MapperFactoryBean> mapperF
136
142
this .mapperFactoryBeanClass = mapperFactoryBeanClass == null ? MapperFactoryBean .class : mapperFactoryBeanClass ;
137
143
}
138
144
145
+ /**
146
+ * Set the default scope of scanned mappers.
147
+ * <p>
148
+ * Default is {@code null} (equiv to singleton).
149
+ * </p>
150
+ *
151
+ * @param defaultScope
152
+ * the scope
153
+ * @since 2.0.6
154
+ */
155
+ public void setDefaultScope (String defaultScope ) {
156
+ this .defaultScope = defaultScope ;
157
+ }
158
+
139
159
/**
140
160
* Configures parent scanner to search for the right interfaces. It can search for all interfaces or just for those
141
161
* that extends a markerInterface or/and those annotated with the annotationClass
@@ -191,9 +211,18 @@ public Set<BeanDefinitionHolder> doScan(String... basePackages) {
191
211
}
192
212
193
213
private void processBeanDefinitions (Set <BeanDefinitionHolder > beanDefinitions ) {
194
- GenericBeanDefinition definition ;
214
+ AbstractBeanDefinition definition ;
215
+ BeanDefinitionRegistry registry = getRegistry ();
195
216
for (BeanDefinitionHolder holder : beanDefinitions ) {
196
- definition = (GenericBeanDefinition ) holder .getBeanDefinition ();
217
+ definition = (AbstractBeanDefinition ) holder .getBeanDefinition ();
218
+ boolean scopedProxy = false ;
219
+ if (ScopedProxyFactoryBean .class .getName ().equals (definition .getBeanClassName ())) {
220
+ definition = (AbstractBeanDefinition ) Optional
221
+ .ofNullable (((RootBeanDefinition ) definition ).getDecoratedDefinition ())
222
+ .map (BeanDefinitionHolder ::getBeanDefinition ).orElseThrow (() -> new IllegalStateException (
223
+ "The target bean definition of scoped proxy bean not found. Root bean definition[" + holder + "]" ));
224
+ scopedProxy = true ;
225
+ }
197
226
String beanClassName = definition .getBeanClassName ();
198
227
LOGGER .debug (() -> "Creating MapperFactoryBean with name '" + holder .getBeanName () + "' and '" + beanClassName
199
228
+ "' mapperInterface" );
@@ -236,7 +265,25 @@ private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
236
265
LOGGER .debug (() -> "Enabling autowire by type for MapperFactoryBean with name '" + holder .getBeanName () + "'." );
237
266
definition .setAutowireMode (AbstractBeanDefinition .AUTOWIRE_BY_TYPE );
238
267
}
268
+
239
269
definition .setLazyInit (lazyInitialization );
270
+
271
+ if (scopedProxy ) {
272
+ continue ;
273
+ }
274
+
275
+ if (ConfigurableBeanFactory .SCOPE_SINGLETON .equals (definition .getScope ()) && defaultScope != null ) {
276
+ definition .setScope (defaultScope );
277
+ }
278
+
279
+ if (!definition .isSingleton ()) {
280
+ BeanDefinitionHolder proxyHolder = ScopedProxyUtils .createScopedProxy (holder , registry , true );
281
+ if (registry .containsBeanDefinition (proxyHolder .getBeanName ())) {
282
+ registry .removeBeanDefinition (proxyHolder .getBeanName ());
283
+ }
284
+ registry .registerBeanDefinition (proxyHolder .getBeanName (), proxyHolder .getBeanDefinition ());
285
+ }
286
+
240
287
}
241
288
}
242
289
0 commit comments