1
1
/*
2
- * Copyright 2002-2018 the original author or authors.
2
+ * Copyright 2002-2019 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.
16
16
17
17
package org .springframework .beans .factory .support ;
18
18
19
- import static org .junit .Assert .assertEquals ;
20
- import static org .junit .Assert .assertFalse ;
21
- import static org .junit .Assert .assertTrue ;
22
- import static org .mockito .ArgumentMatchers .any ;
23
- import static org .mockito .ArgumentMatchers .isNull ;
24
- import static org .mockito .Mockito .when ;
25
-
26
19
import java .lang .reflect .Constructor ;
20
+ import java .lang .reflect .Executable ;
27
21
import java .lang .reflect .Method ;
28
22
import java .lang .reflect .Parameter ;
29
23
import java .util .HashMap ;
30
24
import java .util .Map ;
31
25
26
+ import org .junit .Rule ;
32
27
import org .junit .Test ;
33
- import org .mockito .Mockito ;
28
+ import org .junit .rules .ExpectedException ;
29
+
34
30
import org .springframework .beans .factory .annotation .Autowired ;
35
31
import org .springframework .beans .factory .annotation .Qualifier ;
36
32
import org .springframework .beans .factory .annotation .Value ;
37
33
import org .springframework .beans .factory .config .AutowireCapableBeanFactory ;
38
34
import org .springframework .beans .factory .config .DependencyDescriptor ;
35
+ import org .springframework .util .ClassUtils ;
39
36
import org .springframework .util .ReflectionUtils ;
40
37
38
+ import static org .junit .Assert .*;
39
+ import static org .mockito .ArgumentMatchers .*;
40
+ import static org .mockito .Mockito .*;
41
+
41
42
/**
43
+ * Unit tests for {@link AutowireUtils}.
44
+ *
42
45
* @author Juergen Hoeller
43
46
* @author Sam Brannen
47
+ * @author Loïc Ledoyen
44
48
*/
45
49
public class AutowireUtilsTests {
50
+
51
+ @ Rule
52
+ public final ExpectedException exception = ExpectedException .none ();
46
53
47
54
@ Test
48
55
public void genericMethodReturnTypes () {
@@ -97,46 +104,96 @@ public void genericMethodReturnTypes() {
97
104
}
98
105
99
106
@ Test
100
- public void marked_parameters_are_candidate_for_autowiring () throws NoSuchMethodException {
101
- Constructor <AutowirableClass > autowirableConstructor = ReflectionUtils .accessibleConstructor (
102
- AutowirableClass .class , String .class , String .class , String .class , String .class );
107
+ public void isAutowirablePreconditions () {
108
+ exception .expect (IllegalArgumentException .class );
109
+ exception .expectMessage ("Parameter must not be null" );
110
+ AutowireUtils .isAutowirable (null , 0 );
111
+ }
112
+
113
+ @ Test
114
+ public void annotatedParametersInMethodAreCandidatesForAutowiring () throws Exception {
115
+ Method method = getClass ().getDeclaredMethod ("autowirableMethod" , String .class , String .class , String .class , String .class );
116
+ assertAutowirableParameters (method );
117
+ }
118
+
119
+ @ Test
120
+ public void annotatedParametersInTopLevelClassConstructorAreCandidatesForAutowiring () throws Exception {
121
+ Constructor <?> constructor = AutowirableClass .class .getConstructor (String .class , String .class , String .class , String .class );
122
+ assertAutowirableParameters (constructor );
123
+ }
124
+
125
+ @ Test
126
+ public void annotatedParametersInInnerClassConstructorAreCandidatesForAutowiring () throws Exception {
127
+ Class <?> innerClass = AutowirableClass .InnerAutowirableClass .class ;
128
+ assertTrue (ClassUtils .isInnerClass (innerClass ));
129
+ Constructor <?> constructor = innerClass .getConstructor (AutowirableClass .class , String .class , String .class );
130
+ assertAutowirableParameters (constructor );
131
+ }
103
132
104
- for (int parameterIndex = 0 ; parameterIndex < autowirableConstructor .getParameterCount (); parameterIndex ++) {
105
- Parameter parameter = autowirableConstructor .getParameters ()[parameterIndex ];
133
+ private void assertAutowirableParameters (Executable executable ) {
134
+ int startIndex = (executable instanceof Constructor )
135
+ && ClassUtils .isInnerClass (executable .getDeclaringClass ()) ? 1 : 0 ;
136
+ Parameter [] parameters = executable .getParameters ();
137
+ for (int parameterIndex = startIndex ; parameterIndex < parameters .length ; parameterIndex ++) {
138
+ Parameter parameter = parameters [parameterIndex ];
106
139
assertTrue ("Parameter " + parameter + " must be autowirable" , AutowireUtils .isAutowirable (parameter , parameterIndex ));
107
140
}
108
141
}
109
142
110
143
@ Test
111
- public void not_marked_parameters_are_not_candidate_for_autowiring () throws NoSuchMethodException {
112
- Constructor <AutowirableClass > notAutowirableConstructor = ReflectionUtils . accessibleConstructor ( AutowirableClass .class , String .class );
144
+ public void nonAnnotatedParametersInTopLevelClassConstructorAreNotCandidatesForAutowiring () throws Exception {
145
+ Constructor <? > notAutowirableConstructor = AutowirableClass .class . getConstructor ( String .class );
113
146
114
- for (int parameterIndex = 0 ; parameterIndex < notAutowirableConstructor .getParameterCount (); parameterIndex ++) {
115
- Parameter parameter = notAutowirableConstructor .getParameters ()[parameterIndex ];
116
- assertFalse ("Parameter " + parameter + " must not be autowirable" , AutowireUtils .isAutowirable (parameter , 0 ));
147
+ Parameter [] parameters = notAutowirableConstructor .getParameters ();
148
+ for (int parameterIndex = 0 ; parameterIndex < parameters .length ; parameterIndex ++) {
149
+ Parameter parameter = parameters [parameterIndex ];
150
+ assertFalse ("Parameter " + parameter + " must not be autowirable" , AutowireUtils .isAutowirable (parameter , parameterIndex ));
117
151
}
118
152
}
119
153
120
154
@ Test
121
- public void dependency_resolution_for_marked_parameters () throws NoSuchMethodException {
122
- Constructor <AutowirableClass > autowirableConstructor = ReflectionUtils .accessibleConstructor (
123
- AutowirableClass .class , String .class , String .class , String .class , String .class );
124
- AutowireCapableBeanFactory beanFactory = Mockito .mock (AutowireCapableBeanFactory .class );
125
- // BeanFactory will return the DependencyDescriptor for convenience and to avoid using an ArgumentCaptor
126
- when (beanFactory .resolveDependency (any (), isNull ())).thenAnswer (iom -> iom .getArgument (0 ));
127
-
128
- for (int parameterIndex = 0 ; parameterIndex < autowirableConstructor .getParameterCount (); parameterIndex ++) {
129
- Parameter parameter = autowirableConstructor .getParameters ()[parameterIndex ];
155
+ public void resolveDependencyPreconditionsForParameter () {
156
+ exception .expect (IllegalArgumentException .class );
157
+ exception .expectMessage ("Parameter must not be null" );
158
+ AutowireUtils .resolveDependency (null , 0 , null , mock (AutowireCapableBeanFactory .class ));
159
+ }
160
+
161
+ @ Test
162
+ public void resolveDependencyPreconditionsForBeanFactory () throws Exception {
163
+ Method method = getClass ().getDeclaredMethod ("autowirableMethod" , String .class , String .class , String .class , String .class );
164
+ Parameter parameter = method .getParameters ()[0 ];
165
+
166
+ exception .expect (IllegalArgumentException .class );
167
+ exception .expectMessage ("AutowireCapableBeanFactory must not be null" );
168
+ AutowireUtils .resolveDependency (parameter , 0 , null , null );
169
+ }
170
+
171
+ @ Test
172
+ public void resolveDependencyForAnnotatedParametersInTopLevelClassConstructor () throws Exception {
173
+ Constructor <?> constructor = AutowirableClass .class .getConstructor (String .class , String .class , String .class , String .class );
174
+
175
+ AutowireCapableBeanFactory beanFactory = mock (AutowireCapableBeanFactory .class );
176
+ // Configure the mocked BeanFactory to return the DependencyDescriptor for convenience and
177
+ // to avoid using an ArgumentCaptor.
178
+ when (beanFactory .resolveDependency (any (), isNull ())).thenAnswer (invocation -> invocation .getArgument (0 ));
179
+
180
+ Parameter [] parameters = constructor .getParameters ();
181
+ for (int parameterIndex = 0 ; parameterIndex < parameters .length ; parameterIndex ++) {
182
+ Parameter parameter = parameters [parameterIndex ];
130
183
DependencyDescriptor intermediateDependencyDescriptor = (DependencyDescriptor ) AutowireUtils .resolveDependency (
131
184
parameter , parameterIndex , AutowirableClass .class , beanFactory );
132
- assertEquals (intermediateDependencyDescriptor .getAnnotatedElement (), autowirableConstructor );
133
- assertEquals (intermediateDependencyDescriptor .getMethodParameter ().getParameter (), parameter );
185
+ assertEquals (constructor , intermediateDependencyDescriptor .getAnnotatedElement ());
186
+ assertEquals (parameter , intermediateDependencyDescriptor .getMethodParameter ().getParameter ());
134
187
}
135
188
}
136
189
190
+
137
191
public interface MyInterfaceType <T > {
138
192
}
139
193
194
+ public class MySimpleInterfaceType implements MyInterfaceType <String > {
195
+ }
196
+
140
197
public static class MyTypeWithMethods <T > {
141
198
142
199
/**
@@ -229,7 +286,15 @@ public void readGenericArrayInputMessage(T[] message) {
229
286
}
230
287
}
231
288
289
+ void autowirableMethod (
290
+ @ Autowired String firstParameter ,
291
+ @ Qualifier ("someQualifier" ) String secondParameter ,
292
+ @ Value ("${someValue}" ) String thirdParameter ,
293
+ @ Autowired (required = false ) String fourthParameter ) {
294
+ }
295
+
232
296
public static class AutowirableClass {
297
+
233
298
public AutowirableClass (@ Autowired String firstParameter ,
234
299
@ Qualifier ("someQualifier" ) String secondParameter ,
235
300
@ Value ("${someValue}" ) String thirdParameter ,
@@ -238,8 +303,13 @@ public AutowirableClass(@Autowired String firstParameter,
238
303
239
304
public AutowirableClass (String notAutowirableParameter ) {
240
305
}
241
- }
242
306
243
- public class MySimpleInterfaceType implements MyInterfaceType <String > {
307
+ public class InnerAutowirableClass {
308
+
309
+ public InnerAutowirableClass (@ Autowired String firstParameter ,
310
+ @ Qualifier ("someQualifier" ) String secondParameter ) {
311
+ }
312
+ }
244
313
}
314
+
245
315
}
0 commit comments