@@ -384,13 +384,22 @@ static Class<?> generateCustomAccessorClass(PersistentEntity<?, ?> entity) {
384
384
static byte [] generateBytecode (String internalClassName , PersistentEntity <?, ?> entity ) {
385
385
386
386
ClassWriter cw = new ClassWriter (ClassWriter .COMPUTE_MAXS );
387
- cw .visit (Opcodes .V1_8 , ACC_PUBLIC + ACC_SUPER , internalClassName , null , JAVA_LANG_OBJECT , IMPLEMENTED_INTERFACES );
387
+
388
+ String signature = referenceName (JAVA_LANG_OBJECT ) + String .format ("L%s<%s>;" ,
389
+ Type .getInternalName (PersistentPropertyAccessor .class ), referenceName (entity .getType ()));
390
+
391
+ cw .visit (Opcodes .V1_8 , ACC_PUBLIC + ACC_SUPER , internalClassName , signature , JAVA_LANG_OBJECT ,
392
+ IMPLEMENTED_INTERFACES );
388
393
389
394
List <PersistentProperty <?>> persistentProperties = getPersistentProperties (entity );
390
395
391
396
visitFields (entity , persistentProperties , cw );
392
397
visitDefaultConstructor (entity , internalClassName , cw );
393
- visitStaticInitializer (entity , persistentProperties , internalClassName , cw );
398
+
399
+ if (requiresMethodHandleSetup (entity , persistentProperties )) {
400
+ visitStaticInitializer (entity , persistentProperties , internalClassName , cw );
401
+ }
402
+
394
403
visitBeanGetter (entity , internalClassName , cw );
395
404
visitSetProperty (entity , persistentProperties , internalClassName , cw );
396
405
visitGetProperty (entity , persistentProperties , internalClassName , cw );
@@ -515,9 +524,7 @@ private static void visitDefaultConstructor(PersistentEntity<?, ?> entity, Strin
515
524
* Method getter;
516
525
* Method setter;
517
526
* MethodHandles.Lookup lookup = MethodHandles.lookup();
518
- * Class class_1 = Class.forName("org.springframework.data.mapping.Person");
519
- * Class class_2 = Class.forName("org.springframework.data.mapping.PersonWithId");
520
- * Field field = class_2.getDeclaredField("id");
527
+ * Field field = org.springframework.data.mapping.PersonWithId.class.getDeclaredField("id");
521
528
* field.setAccessible(true);
522
529
* $id_fieldGetter = lookup.unreflectGetter(field);
523
530
* $id_fieldSetter = lookup.unreflectSetter(field);
@@ -539,37 +546,27 @@ private static void visitStaticInitializer(PersistentEntity<?, ?> entity,
539
546
String .format ("()%s" , referenceName (JAVA_LANG_INVOKE_METHOD_HANDLES_LOOKUP )), false );
540
547
mv .visitVarInsn (ASTORE , 0 );
541
548
542
- List <Class <?>> entityClasses = getPropertyDeclaratingClasses (persistentProperties );
543
-
544
- for (Class <?> entityClass : entityClasses ) {
545
-
546
- mv .visitLdcInsn (entityClass .getName ());
547
- mv .visitMethodInsn (INVOKESTATIC , JAVA_LANG_CLASS , "forName" ,
548
- String .format ("(%s)%s" , referenceName (JAVA_LANG_STRING ), referenceName (JAVA_LANG_CLASS )), false );
549
- mv .visitVarInsn (ASTORE , classVariableIndex5 (entityClasses , entityClass ));
550
- }
551
-
552
549
for (PersistentProperty <?> property : persistentProperties ) {
553
550
554
551
if (property .usePropertyAccess ()) {
555
552
556
553
if (generateMethodHandle (entity , property .getGetter ())) {
557
- visitPropertyGetterInitializer (property , mv , entityClasses , internalClassName );
554
+ visitPropertyGetterInitializer (property , mv , internalClassName );
558
555
}
559
556
560
557
if (generateMethodHandle (entity , property .getSetter ())) {
561
- visitPropertySetterInitializer (property .getSetter (), property , mv , entityClasses , internalClassName ,
558
+ visitPropertySetterInitializer (property .getSetter (), property , mv , internalClassName ,
562
559
PropertyAccessorClassGenerator ::setterName , 2 );
563
560
}
564
561
}
565
562
566
563
if (property .isImmutable () && generateMethodHandle (entity , property .getWither ())) {
567
- visitPropertySetterInitializer (property .getWither (), property , mv , entityClasses , internalClassName ,
564
+ visitPropertySetterInitializer (property .getWither (), property , mv , internalClassName ,
568
565
PropertyAccessorClassGenerator ::witherName , 4 );
569
566
}
570
567
571
568
if (generateSetterMethodHandle (entity , property .getField ())) {
572
- visitFieldGetterSetterInitializer (property , mv , entityClasses , internalClassName );
569
+ visitFieldGetterSetterInitializer (property , mv , internalClassName );
573
570
}
574
571
}
575
572
@@ -582,14 +579,36 @@ private static void visitStaticInitializer(PersistentEntity<?, ?> entity,
582
579
mv .visitLocalVariable ("getter" , referenceName (JAVA_LANG_REFLECT_METHOD ), null , l0 , l1 , 3 );
583
580
mv .visitLocalVariable ("wither" , referenceName (JAVA_LANG_REFLECT_METHOD ), null , l0 , l1 , 4 );
584
581
585
- for (Class <?> entityClass : entityClasses ) {
582
+ mv .visitMaxs (0 , 0 );
583
+ mv .visitEnd ();
584
+ }
585
+
586
+ static boolean requiresMethodHandleSetup (PersistentEntity <?, ?> entity ,
587
+ List <PersistentProperty <?>> persistentProperties ) {
588
+
589
+ for (PersistentProperty <?> property : persistentProperties ) {
590
+
591
+ if (property .usePropertyAccess ()) {
592
+
593
+ if (generateMethodHandle (entity , property .getGetter ())) {
594
+ return true ;
595
+ }
596
+
597
+ if (generateMethodHandle (entity , property .getSetter ())) {
598
+ return true ;
599
+ }
600
+ }
601
+
602
+ if (property .isImmutable () && generateMethodHandle (entity , property .getWither ())) {
603
+ return true ;
604
+ }
586
605
587
- int index = classVariableIndex5 (entityClasses , entityClass );
588
- mv .visitLocalVariable (String .format ("class_%d" , index ), referenceName (JAVA_LANG_CLASS ), null , l0 , l1 , index );
606
+ if (generateSetterMethodHandle (entity , property .getField ())) {
607
+ return true ;
608
+ }
589
609
}
590
610
591
- mv .visitMaxs (0 , 0 );
592
- mv .visitEnd ();
611
+ return false ;
593
612
}
594
613
595
614
/**
@@ -617,14 +636,14 @@ private static List<Class<?>> getPropertyDeclaratingClasses(List<PersistentPrope
617
636
* Generate property getter initializer.
618
637
*/
619
638
private static void visitPropertyGetterInitializer (PersistentProperty <?> property , MethodVisitor mv ,
620
- List < Class <?>> entityClasses , String internalClassName ) {
639
+ String internalClassName ) {
621
640
622
641
// getter = <entity>.class.getDeclaredMethod()
623
642
Method getter = property .getGetter ();
624
643
625
644
if (getter != null ) {
626
645
627
- mv .visitVarInsn ( ALOAD , classVariableIndex5 ( entityClasses , getter .getDeclaringClass ()));
646
+ mv .visitLdcInsn ( Type . getObjectType ( Type . getInternalName ( getter .getDeclaringClass () )));
628
647
mv .visitLdcInsn (getter .getName ());
629
648
mv .visitInsn (ICONST_0 );
630
649
mv .visitTypeInsn (ANEWARRAY , JAVA_LANG_CLASS );
@@ -657,14 +676,14 @@ private static void visitPropertyGetterInitializer(PersistentProperty<?> propert
657
676
* Generate property setter/wither initializer.
658
677
*/
659
678
private static void visitPropertySetterInitializer (@ Nullable Method method , PersistentProperty <?> property ,
660
- MethodVisitor mv , List < Class <?>> entityClasses , String internalClassName ,
679
+ MethodVisitor mv , String internalClassName ,
661
680
Function <PersistentProperty <?>, String > setterNameFunction , int localVariableIndex ) {
662
681
663
682
// method = <entity>.class.getDeclaredMethod()
664
683
665
684
if (method != null ) {
666
685
667
- mv .visitVarInsn ( ALOAD , classVariableIndex5 ( entityClasses , method .getDeclaringClass ()));
686
+ mv .visitLdcInsn ( Type . getObjectType ( Type . getInternalName ( method .getDeclaringClass () )));
668
687
mv .visitLdcInsn (method .getName ());
669
688
670
689
mv .visitInsn (ICONST_1 );
@@ -711,14 +730,14 @@ private static void visitPropertySetterInitializer(@Nullable Method method, Pers
711
730
* Generate field getter and setter initializers.
712
731
*/
713
732
private static void visitFieldGetterSetterInitializer (PersistentProperty <?> property , MethodVisitor mv ,
714
- List < Class <?>> entityClasses , String internalClassName ) {
733
+ String internalClassName ) {
715
734
716
735
// field = <entity>.class.getDeclaredField()
717
736
718
737
Field field = property .getField ();
719
738
if (field != null ) {
720
739
721
- mv .visitVarInsn ( ALOAD , classVariableIndex5 ( entityClasses , field .getDeclaringClass ()));
740
+ mv .visitLdcInsn ( Type . getObjectType ( Type . getInternalName ( field .getDeclaringClass () )));
722
741
mv .visitLdcInsn (field .getName ());
723
742
mv .visitMethodInsn (INVOKEVIRTUAL , JAVA_LANG_CLASS , "getDeclaredField" ,
724
743
String .format ("(%s)%s" , referenceName (JAVA_LANG_STRING ), referenceName (JAVA_LANG_REFLECT_FIELD )), false );
0 commit comments