@@ -153,11 +153,20 @@ public void setConstructorArguments(@Nullable Object[] constructorArgs, @Nullabl
153
153
154
154
@ Override
155
155
public Object getProxy () {
156
- return getProxy (null );
156
+ return buildProxy (null , false );
157
157
}
158
158
159
159
@ Override
160
160
public Object getProxy (@ Nullable ClassLoader classLoader ) {
161
+ return buildProxy (classLoader , false );
162
+ }
163
+
164
+ @ Override
165
+ public Class <?> getProxyClass (@ Nullable ClassLoader classLoader ) {
166
+ return (Class <?>) buildProxy (classLoader , true );
167
+ }
168
+
169
+ private Object buildProxy (@ Nullable ClassLoader classLoader , boolean classOnly ) {
161
170
if (logger .isTraceEnabled ()) {
162
171
logger .trace ("Creating CGLIB proxy: " + this .advised .getTargetSource ());
163
172
}
@@ -190,6 +199,7 @@ public Object getProxy(@Nullable ClassLoader classLoader) {
190
199
enhancer .setSuperclass (proxySuperClass );
191
200
enhancer .setInterfaces (AopProxyUtils .completeProxiedInterfaces (this .advised ));
192
201
enhancer .setNamingPolicy (SpringNamingPolicy .INSTANCE );
202
+ enhancer .setAttemptLoad (true );
193
203
enhancer .setStrategy (new ClassLoaderAwareGeneratorStrategy (classLoader ));
194
204
195
205
Callback [] callbacks = getCallbacks (rootClass );
@@ -203,7 +213,7 @@ public Object getProxy(@Nullable ClassLoader classLoader) {
203
213
enhancer .setCallbackTypes (types );
204
214
205
215
// Generate the proxy class and create a proxy instance.
206
- return createProxyClassAndInstance (enhancer , callbacks );
216
+ return ( classOnly ? createProxyClass ( enhancer ) : createProxyClassAndInstance (enhancer , callbacks ) );
207
217
}
208
218
catch (CodeGenerationException | IllegalArgumentException ex ) {
209
219
throw new AopConfigException ("Could not generate CGLIB subclass of " + this .advised .getTargetClass () +
@@ -216,6 +226,11 @@ public Object getProxy(@Nullable ClassLoader classLoader) {
216
226
}
217
227
}
218
228
229
+ protected Class <?> createProxyClass (Enhancer enhancer ) {
230
+ enhancer .setInterceptDuringConstruction (false );
231
+ return enhancer .createClass ();
232
+ }
233
+
219
234
protected Object createProxyClassAndInstance (Enhancer enhancer , Callback [] callbacks ) {
220
235
enhancer .setInterceptDuringConstruction (false );
221
236
enhancer .setCallbacks (callbacks );
@@ -375,22 +390,6 @@ private static boolean implementsInterface(Method method, Set<Class<?>> ifcs) {
375
390
return false ;
376
391
}
377
392
378
- /**
379
- * Invoke the given method with a CGLIB MethodProxy if possible, falling back
380
- * to a plain reflection invocation in case of a fast-class generation failure.
381
- */
382
- @ Nullable
383
- private static Object invokeMethod (@ Nullable Object target , Method method , Object [] args , MethodProxy methodProxy )
384
- throws Throwable {
385
- try {
386
- return methodProxy .invoke (target , args );
387
- }
388
- catch (CodeGenerationException ex ) {
389
- CglibMethodInvocation .logFastClassGenerationFailure (method );
390
- return AopUtils .invokeJoinpointUsingReflection (target , method , args );
391
- }
392
- }
393
-
394
393
/**
395
394
* Process a return value. Wraps a return of {@code this} if necessary to be the
396
395
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
@@ -424,10 +423,9 @@ public static class SerializableNoOp implements NoOp, Serializable {
424
423
425
424
426
425
/**
427
- * Method interceptor used for static targets with no advice chain. The call
428
- * is passed directly back to the target. Used when the proxy needs to be
429
- * exposed and it can't be determined that the method won't return
430
- * {@code this}.
426
+ * Method interceptor used for static targets with no advice chain. The call is
427
+ * passed directly back to the target. Used when the proxy needs to be exposed
428
+ * and it can't be determined that the method won't return {@code this}.
431
429
*/
432
430
private static class StaticUnadvisedInterceptor implements MethodInterceptor , Serializable {
433
431
@@ -441,7 +439,7 @@ public StaticUnadvisedInterceptor(@Nullable Object target) {
441
439
@ Override
442
440
@ Nullable
443
441
public Object intercept (Object proxy , Method method , Object [] args , MethodProxy methodProxy ) throws Throwable {
444
- Object retVal = invokeMethod (this .target , method , args , methodProxy );
442
+ Object retVal = AopUtils . invokeJoinpointUsingReflection (this .target , method , args );
445
443
return processReturnType (proxy , this .target , method , retVal );
446
444
}
447
445
}
@@ -466,7 +464,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
466
464
Object oldProxy = null ;
467
465
try {
468
466
oldProxy = AopContext .setCurrentProxy (proxy );
469
- Object retVal = invokeMethod (this .target , method , args , methodProxy );
467
+ Object retVal = AopUtils . invokeJoinpointUsingReflection (this .target , method , args );
470
468
return processReturnType (proxy , this .target , method , retVal );
471
469
}
472
470
finally {
@@ -494,7 +492,7 @@ public DynamicUnadvisedInterceptor(TargetSource targetSource) {
494
492
public Object intercept (Object proxy , Method method , Object [] args , MethodProxy methodProxy ) throws Throwable {
495
493
Object target = this .targetSource .getTarget ();
496
494
try {
497
- Object retVal = invokeMethod (target , method , args , methodProxy );
495
+ Object retVal = AopUtils . invokeJoinpointUsingReflection (target , method , args );
498
496
return processReturnType (proxy , target , method , retVal );
499
497
}
500
498
finally {
@@ -524,7 +522,7 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
524
522
Object target = this .targetSource .getTarget ();
525
523
try {
526
524
oldProxy = AopContext .setCurrentProxy (proxy );
527
- Object retVal = invokeMethod (target , method , args , methodProxy );
525
+ Object retVal = AopUtils . invokeJoinpointUsingReflection (target , method , args );
528
526
return processReturnType (proxy , target , method , retVal );
529
527
}
530
528
finally {
@@ -695,13 +693,13 @@ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy
695
693
Object retVal ;
696
694
// Check whether we only have one InvokerInterceptor: that is,
697
695
// no real advice, but just reflective invocation of the target.
698
- if (chain .isEmpty () && CglibMethodInvocation . isMethodProxyCompatible ( method ) ) {
696
+ if (chain .isEmpty ()) {
699
697
// We can skip creating a MethodInvocation: just invoke the target directly.
700
698
// Note that the final invoker must be an InvokerInterceptor, so we know
701
699
// it does nothing but a reflective operation on the target, and no hot
702
700
// swapping or fancy proxying.
703
701
Object [] argsToUse = AopProxyUtils .adaptArgumentsIfNecessary (method , args );
704
- retVal = invokeMethod (target , method , argsToUse , methodProxy );
702
+ retVal = AopUtils . invokeJoinpointUsingReflection (target , method , argsToUse );
705
703
}
706
704
else {
707
705
// We need to create a method invocation...
@@ -743,17 +741,11 @@ public int hashCode() {
743
741
*/
744
742
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
745
743
746
- @ Nullable
747
- private final MethodProxy methodProxy ;
748
-
749
744
public CglibMethodInvocation (Object proxy , @ Nullable Object target , Method method ,
750
745
Object [] arguments , @ Nullable Class <?> targetClass ,
751
746
List <Object > interceptorsAndDynamicMethodMatchers , MethodProxy methodProxy ) {
752
747
753
748
super (proxy , target , method , arguments , targetClass , interceptorsAndDynamicMethodMatchers );
754
-
755
- // Only use method proxy for public methods not derived from java.lang.Object
756
- this .methodProxy = (isMethodProxyCompatible (method ) ? methodProxy : null );
757
749
}
758
750
759
751
@ Override
@@ -781,35 +773,6 @@ public Object proceed() throws Throwable {
781
773
}
782
774
}
783
775
}
784
-
785
- /**
786
- * Gives a marginal performance improvement versus using reflection to
787
- * invoke the target when invoking public methods.
788
- */
789
- @ Override
790
- protected Object invokeJoinpoint () throws Throwable {
791
- if (this .methodProxy != null ) {
792
- try {
793
- return this .methodProxy .invoke (this .target , this .arguments );
794
- }
795
- catch (CodeGenerationException ex ) {
796
- logFastClassGenerationFailure (this .method );
797
- }
798
- }
799
- return super .invokeJoinpoint ();
800
- }
801
-
802
- static boolean isMethodProxyCompatible (Method method ) {
803
- return (Modifier .isPublic (method .getModifiers ()) &&
804
- method .getDeclaringClass () != Object .class && !AopUtils .isEqualsMethod (method ) &&
805
- !AopUtils .isHashCodeMethod (method ) && !AopUtils .isToStringMethod (method ));
806
- }
807
-
808
- static void logFastClassGenerationFailure (Method method ) {
809
- if (logger .isDebugEnabled ()) {
810
- logger .debug ("Failed to generate CGLIB fast class for method: " + method );
811
- }
812
- }
813
776
}
814
777
815
778
0 commit comments