19
19
import java .lang .reflect .InvocationTargetException ;
20
20
import java .lang .reflect .Method ;
21
21
import java .lang .reflect .Modifier ;
22
+ import java .lang .reflect .Proxy ;
22
23
import java .util .Map ;
23
24
24
25
import org .apache .ibatis .annotations .Lang ;
26
+ import org .apache .ibatis .annotations .SelectProvider ;
25
27
import org .apache .ibatis .builder .BuilderException ;
26
28
import org .apache .ibatis .mapping .BoundSql ;
27
29
import org .apache .ibatis .mapping .SqlSource ;
@@ -46,7 +48,8 @@ public class ProviderSqlSource implements SqlSource {
46
48
private Integer providerContextIndex ;
47
49
48
50
/**
49
- * @deprecated Please use the {@link #ProviderSqlSource(Configuration, Object, Class, Method)} instead of this.
51
+ * @deprecated Since 3.5.3, Please use the {@link #ProviderSqlSource(Configuration, Annotation, Class, Method)} instead of this.
52
+ * This constructor will remove at a future version.
50
53
*/
51
54
@ Deprecated
52
55
public ProviderSqlSource (Configuration configuration , Object provider ) {
@@ -55,16 +58,34 @@ public ProviderSqlSource(Configuration configuration, Object provider) {
55
58
56
59
/**
57
60
* @since 3.4.5
61
+ * @deprecated Since 3.5.3, Please use the {@link #ProviderSqlSource(Configuration, Annotation, Class, Method)} instead of this.
62
+ * This constructor will remove at a future version.
58
63
*/
64
+ @ Deprecated
59
65
public ProviderSqlSource (Configuration configuration , Object provider , Class <?> mapperType , Method mapperMethod ) {
66
+ this (configuration , provider instanceof Annotation ? (Annotation ) provider :
67
+ (Annotation ) Proxy .newProxyInstance (SelectProvider .class .getClassLoader (), new Class <?>[]{SelectProvider .class },
68
+ (proxy , method , args ) -> {
69
+ if (method .getName ().equals ("annotationType" )) {
70
+ return SelectProvider .class ;
71
+ }
72
+ return provider .getClass ().getMethod (method .getName ()).invoke (provider );
73
+ }),
74
+ mapperType , mapperMethod );
75
+ }
76
+
77
+ /**
78
+ * @since 3.5.3
79
+ */
80
+ public ProviderSqlSource (Configuration configuration , Annotation provider , Class <?> mapperType , Method mapperMethod ) {
60
81
String providerMethodName ;
61
82
try {
62
83
this .configuration = configuration ;
63
84
this .mapperMethod = mapperMethod ;
64
85
Lang lang = mapperMethod == null ? null : mapperMethod .getAnnotation (Lang .class );
65
86
this .languageDriver = configuration .getLanguageDriver (lang == null ? null : lang .value ());
66
87
this .providerType = getProviderType (provider , mapperMethod );
67
- providerMethodName = (String ) provider .getClass ().getMethod ("method" ).invoke (provider );
88
+ providerMethodName = (String ) provider .annotationType ().getMethod ("method" ).invoke (provider );
68
89
69
90
if (providerMethodName .length () == 0 && ProviderMethodResolver .class .isAssignableFrom (this .providerType )) {
70
91
this .providerMethod = ((ProviderMethodResolver ) this .providerType .getDeclaredConstructor ().newInstance ())
@@ -192,18 +213,18 @@ private String invokeProviderMethod(Object... args) throws Exception {
192
213
return sql != null ? sql .toString () : null ;
193
214
}
194
215
195
- private Class <?> getProviderType (Object providerAnnotation , Method mapperMethod )
216
+ private Class <?> getProviderType (Annotation providerAnnotation , Method mapperMethod )
196
217
throws NoSuchMethodException , InvocationTargetException , IllegalAccessException {
197
- Class <?> type = (Class <?>) providerAnnotation .getClass ().getMethod ("type" ).invoke (providerAnnotation );
198
- Class <?> value = (Class <?>) providerAnnotation .getClass ().getMethod ("value" ).invoke (providerAnnotation );
218
+ Class <?> type = (Class <?>) providerAnnotation .annotationType ().getMethod ("type" ).invoke (providerAnnotation );
219
+ Class <?> value = (Class <?>) providerAnnotation .annotationType ().getMethod ("value" ).invoke (providerAnnotation );
199
220
if (value == void .class && type == void .class ) {
200
221
throw new BuilderException ("Please specify either 'value' or 'type' attribute of @"
201
- + (( Annotation ) providerAnnotation ) .annotationType ().getSimpleName ()
222
+ + providerAnnotation .annotationType ().getSimpleName ()
202
223
+ " at the '" + mapperMethod .toString () + "'." );
203
224
}
204
225
if (value != void .class && type != void .class && value != type ) {
205
226
throw new BuilderException ("Cannot specify different class on 'value' and 'type' attribute of @"
206
- + (( Annotation ) providerAnnotation ) .annotationType ().getSimpleName ()
227
+ + providerAnnotation .annotationType ().getSimpleName ()
207
228
+ " at the '" + mapperMethod .toString () + "'." );
208
229
}
209
230
return value == void .class ? type : value ;
0 commit comments