@@ -384,13 +384,22 @@ static Class<?> generateCustomAccessorClass(PersistentEntity<?, ?> entity) {
384384 static byte [] generateBytecode (String internalClassName , PersistentEntity <?, ?> entity ) {
385385
386386 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 );
388393
389394 List <PersistentProperty <?>> persistentProperties = getPersistentProperties (entity );
390395
391396 visitFields (entity , persistentProperties , cw );
392397 visitDefaultConstructor (entity , internalClassName , cw );
393- visitStaticInitializer (entity , persistentProperties , internalClassName , cw );
398+
399+ if (requiresMethodHandleSetup (entity , persistentProperties )) {
400+ visitStaticInitializer (entity , persistentProperties , internalClassName , cw );
401+ }
402+
394403 visitBeanGetter (entity , internalClassName , cw );
395404 visitSetProperty (entity , persistentProperties , internalClassName , cw );
396405 visitGetProperty (entity , persistentProperties , internalClassName , cw );
@@ -515,9 +524,7 @@ private static void visitDefaultConstructor(PersistentEntity<?, ?> entity, Strin
515524 * Method getter;
516525 * Method setter;
517526 * 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");
521528 * field.setAccessible(true);
522529 * $id_fieldGetter = lookup.unreflectGetter(field);
523530 * $id_fieldSetter = lookup.unreflectSetter(field);
@@ -539,37 +546,27 @@ private static void visitStaticInitializer(PersistentEntity<?, ?> entity,
539546 String .format ("()%s" , referenceName (JAVA_LANG_INVOKE_METHOD_HANDLES_LOOKUP )), false );
540547 mv .visitVarInsn (ASTORE , 0 );
541548
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-
552549 for (PersistentProperty <?> property : persistentProperties ) {
553550
554551 if (property .usePropertyAccess ()) {
555552
556553 if (generateMethodHandle (entity , property .getGetter ())) {
557- visitPropertyGetterInitializer (property , mv , entityClasses , internalClassName );
554+ visitPropertyGetterInitializer (property , mv , internalClassName );
558555 }
559556
560557 if (generateMethodHandle (entity , property .getSetter ())) {
561- visitPropertySetterInitializer (property .getSetter (), property , mv , entityClasses , internalClassName ,
558+ visitPropertySetterInitializer (property .getSetter (), property , mv , internalClassName ,
562559 PropertyAccessorClassGenerator ::setterName , 2 );
563560 }
564561 }
565562
566563 if (property .isImmutable () && generateMethodHandle (entity , property .getWither ())) {
567- visitPropertySetterInitializer (property .getWither (), property , mv , entityClasses , internalClassName ,
564+ visitPropertySetterInitializer (property .getWither (), property , mv , internalClassName ,
568565 PropertyAccessorClassGenerator ::witherName , 4 );
569566 }
570567
571568 if (generateSetterMethodHandle (entity , property .getField ())) {
572- visitFieldGetterSetterInitializer (property , mv , entityClasses , internalClassName );
569+ visitFieldGetterSetterInitializer (property , mv , internalClassName );
573570 }
574571 }
575572
@@ -582,14 +579,36 @@ private static void visitStaticInitializer(PersistentEntity<?, ?> entity,
582579 mv .visitLocalVariable ("getter" , referenceName (JAVA_LANG_REFLECT_METHOD ), null , l0 , l1 , 3 );
583580 mv .visitLocalVariable ("wither" , referenceName (JAVA_LANG_REFLECT_METHOD ), null , l0 , l1 , 4 );
584581
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+ }
586605
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+ }
589609 }
590610
591- mv .visitMaxs (0 , 0 );
592- mv .visitEnd ();
611+ return false ;
593612 }
594613
595614 /**
@@ -617,14 +636,14 @@ private static List<Class<?>> getPropertyDeclaratingClasses(List<PersistentPrope
617636 * Generate property getter initializer.
618637 */
619638 private static void visitPropertyGetterInitializer (PersistentProperty <?> property , MethodVisitor mv ,
620- List < Class <?>> entityClasses , String internalClassName ) {
639+ String internalClassName ) {
621640
622641 // getter = <entity>.class.getDeclaredMethod()
623642 Method getter = property .getGetter ();
624643
625644 if (getter != null ) {
626645
627- mv .visitVarInsn ( ALOAD , classVariableIndex5 ( entityClasses , getter .getDeclaringClass ()));
646+ mv .visitLdcInsn ( Type . getObjectType ( Type . getInternalName ( getter .getDeclaringClass () )));
628647 mv .visitLdcInsn (getter .getName ());
629648 mv .visitInsn (ICONST_0 );
630649 mv .visitTypeInsn (ANEWARRAY , JAVA_LANG_CLASS );
@@ -657,14 +676,14 @@ private static void visitPropertyGetterInitializer(PersistentProperty<?> propert
657676 * Generate property setter/wither initializer.
658677 */
659678 private static void visitPropertySetterInitializer (@ Nullable Method method , PersistentProperty <?> property ,
660- MethodVisitor mv , List < Class <?>> entityClasses , String internalClassName ,
679+ MethodVisitor mv , String internalClassName ,
661680 Function <PersistentProperty <?>, String > setterNameFunction , int localVariableIndex ) {
662681
663682 // method = <entity>.class.getDeclaredMethod()
664683
665684 if (method != null ) {
666685
667- mv .visitVarInsn ( ALOAD , classVariableIndex5 ( entityClasses , method .getDeclaringClass ()));
686+ mv .visitLdcInsn ( Type . getObjectType ( Type . getInternalName ( method .getDeclaringClass () )));
668687 mv .visitLdcInsn (method .getName ());
669688
670689 mv .visitInsn (ICONST_1 );
@@ -711,14 +730,14 @@ private static void visitPropertySetterInitializer(@Nullable Method method, Pers
711730 * Generate field getter and setter initializers.
712731 */
713732 private static void visitFieldGetterSetterInitializer (PersistentProperty <?> property , MethodVisitor mv ,
714- List < Class <?>> entityClasses , String internalClassName ) {
733+ String internalClassName ) {
715734
716735 // field = <entity>.class.getDeclaredField()
717736
718737 Field field = property .getField ();
719738 if (field != null ) {
720739
721- mv .visitVarInsn ( ALOAD , classVariableIndex5 ( entityClasses , field .getDeclaringClass ()));
740+ mv .visitLdcInsn ( Type . getObjectType ( Type . getInternalName ( field .getDeclaringClass () )));
722741 mv .visitLdcInsn (field .getName ());
723742 mv .visitMethodInsn (INVOKEVIRTUAL , JAVA_LANG_CLASS , "getDeclaredField" ,
724743 String .format ("(%s)%s" , referenceName (JAVA_LANG_STRING ), referenceName (JAVA_LANG_REFLECT_FIELD )), false );
0 commit comments