42
42
import org .springframework .beans .testfixture .beans .DerivedTestBean ;
43
43
import org .springframework .beans .testfixture .beans .ITestBean ;
44
44
import org .springframework .beans .testfixture .beans .TestBean ;
45
+ import org .springframework .cglib .proxy .Enhancer ;
46
+ import org .springframework .cglib .proxy .MethodInterceptor ;
45
47
import org .springframework .core .io .Resource ;
46
48
import org .springframework .core .io .ResourceEditor ;
47
49
import org .springframework .lang .Nullable ;
@@ -322,12 +324,13 @@ void copyPropertiesIgnoresGenericsIfSourceOrTargetHasUnresolvableGenerics() thro
322
324
Order original = new Order ("test" , List .of ("foo" , "bar" ));
323
325
324
326
// Create a Proxy that loses the generic type information for the getLineItems() method.
325
- OrderSummary proxy = proxyOrder (original );
327
+ OrderSummary proxy = (OrderSummary ) Proxy .newProxyInstance (getClass ().getClassLoader (),
328
+ new Class <?>[] {OrderSummary .class }, new OrderInvocationHandler (original ));
326
329
assertThat (OrderSummary .class .getDeclaredMethod ("getLineItems" ).toGenericString ())
327
- .contains ("java.util.List<java.lang.String>" );
330
+ .contains ("java.util.List<java.lang.String>" );
328
331
assertThat (proxy .getClass ().getDeclaredMethod ("getLineItems" ).toGenericString ())
329
- .contains ("java.util.List" )
330
- .doesNotContain ("<java.lang.String>" );
332
+ .contains ("java.util.List" )
333
+ .doesNotContain ("<java.lang.String>" );
331
334
332
335
// Ensure that our custom Proxy works as expected.
333
336
assertThat (proxy .getId ()).isEqualTo ("test" );
@@ -340,6 +343,23 @@ void copyPropertiesIgnoresGenericsIfSourceOrTargetHasUnresolvableGenerics() thro
340
343
assertThat (target .getLineItems ()).containsExactly ("foo" , "bar" );
341
344
}
342
345
346
+ @ Test // gh-32888
347
+ public void copyPropertiesWithGenericCglibCLass () {
348
+ Enhancer enhancer = new Enhancer ();
349
+ enhancer .setSuperclass (User .class );
350
+ enhancer .setCallback ((MethodInterceptor ) (obj , method , args , proxy ) -> proxy .invokeSuper (obj , args ));
351
+ User user = (User ) enhancer .create ();
352
+ user .setId (1 );
353
+ user .setName ("proxy" );
354
+ user .setAddress ("addr" );
355
+
356
+ User target = new User ();
357
+ BeanUtils .copyProperties (user , target );
358
+ assertThat (target .getId ()).isEqualTo (user .getId ());
359
+ assertThat (target .getName ()).isEqualTo (user .getName ());
360
+ assertThat (target .getAddress ()).isEqualTo (user .getAddress ());
361
+ }
362
+
343
363
@ Test
344
364
void copyPropertiesWithEditable () throws Exception {
345
365
TestBean tb = new TestBean ();
@@ -520,6 +540,7 @@ public void setNumber(Number number) {
520
540
}
521
541
}
522
542
543
+
523
544
@ SuppressWarnings ("unused" )
524
545
private static class IntegerHolder {
525
546
@@ -534,6 +555,7 @@ public void setNumber(Integer number) {
534
555
}
535
556
}
536
557
558
+
537
559
@ SuppressWarnings ("unused" )
538
560
private static class WildcardListHolder1 {
539
561
@@ -548,6 +570,7 @@ public void setList(List<?> list) {
548
570
}
549
571
}
550
572
573
+
551
574
@ SuppressWarnings ("unused" )
552
575
private static class WildcardListHolder2 {
553
576
@@ -562,6 +585,7 @@ public void setList(List<?> list) {
562
585
}
563
586
}
564
587
588
+
565
589
@ SuppressWarnings ("unused" )
566
590
private static class NumberUpperBoundedWildcardListHolder {
567
591
@@ -576,6 +600,7 @@ public void setList(List<? extends Number> list) {
576
600
}
577
601
}
578
602
603
+
579
604
@ SuppressWarnings ("unused" )
580
605
private static class NumberListHolder {
581
606
@@ -590,6 +615,7 @@ public void setList(List<Number> list) {
590
615
}
591
616
}
592
617
618
+
593
619
@ SuppressWarnings ("unused" )
594
620
private static class IntegerListHolder1 {
595
621
@@ -604,6 +630,7 @@ public void setList(List<Integer> list) {
604
630
}
605
631
}
606
632
633
+
607
634
@ SuppressWarnings ("unused" )
608
635
private static class IntegerListHolder2 {
609
636
@@ -618,6 +645,7 @@ public void setList(List<Integer> list) {
618
645
}
619
646
}
620
647
648
+
621
649
@ SuppressWarnings ("unused" )
622
650
private static class LongListHolder {
623
651
@@ -798,6 +826,7 @@ public void setValue(String aValue) {
798
826
}
799
827
}
800
828
829
+
801
830
private static class BeanWithNullableTypes {
802
831
803
832
private Integer counter ;
@@ -828,6 +857,7 @@ public String getValue() {
828
857
}
829
858
}
830
859
860
+
831
861
private static class BeanWithPrimitiveTypes {
832
862
833
863
private boolean flag ;
@@ -840,7 +870,6 @@ private static class BeanWithPrimitiveTypes {
840
870
private char character ;
841
871
private String text ;
842
872
843
-
844
873
@ SuppressWarnings ("unused" )
845
874
public BeanWithPrimitiveTypes (boolean flag , byte byteCount , short shortCount , int intCount , long longCount ,
846
875
float floatCount , double doubleCount , char character , String text ) {
@@ -891,22 +920,22 @@ public char getCharacter() {
891
920
public String getText () {
892
921
return text ;
893
922
}
894
-
895
923
}
896
924
925
+
897
926
private static class PrivateBeanWithPrivateConstructor {
898
927
899
928
private PrivateBeanWithPrivateConstructor () {
900
929
}
901
930
}
902
931
932
+
903
933
@ SuppressWarnings ("unused" )
904
934
private static class Order {
905
935
906
936
private String id ;
907
937
private List <String > lineItems ;
908
938
909
-
910
939
Order () {
911
940
}
912
941
@@ -937,6 +966,7 @@ public String toString() {
937
966
}
938
967
}
939
968
969
+
940
970
private interface OrderSummary {
941
971
942
972
String getId ();
@@ -945,17 +975,10 @@ private interface OrderSummary {
945
975
}
946
976
947
977
948
- private OrderSummary proxyOrder (Order order ) {
949
- return (OrderSummary ) Proxy .newProxyInstance (getClass ().getClassLoader (),
950
- new Class <?>[] { OrderSummary .class }, new OrderInvocationHandler (order ));
951
- }
952
-
953
-
954
978
private static class OrderInvocationHandler implements InvocationHandler {
955
979
956
980
private final Order order ;
957
981
958
-
959
982
OrderInvocationHandler (Order order ) {
960
983
this .order = order ;
961
984
}
@@ -973,4 +996,48 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
973
996
}
974
997
}
975
998
999
+
1000
+ private static class GenericBaseModel <T > {
1001
+
1002
+ public GenericBaseModel () {
1003
+ }
1004
+
1005
+ private T id ;
1006
+ private String name ;
1007
+
1008
+ public T getId () {
1009
+ return id ;
1010
+ }
1011
+
1012
+ public void setId (T id ) {
1013
+ this .id = id ;
1014
+ }
1015
+
1016
+ public String getName () {
1017
+ return name ;
1018
+ }
1019
+
1020
+ public void setName (String name ) {
1021
+ this .name = name ;
1022
+ }
1023
+ }
1024
+
1025
+
1026
+ private static class User extends GenericBaseModel <Integer > {
1027
+
1028
+ private String address ;
1029
+
1030
+ public User () {
1031
+ super ();
1032
+ }
1033
+
1034
+ public String getAddress () {
1035
+ return address ;
1036
+ }
1037
+
1038
+ public void setAddress (String address ) {
1039
+ this .address = address ;
1040
+ }
1041
+ }
1042
+
976
1043
}
0 commit comments