Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1a45458

Browse files
committed
Polishing.
Add generic signature, skip static initializer if not required, access classes in static initializer through constants instead of using forName(...). See #3365
1 parent 4c7a76a commit 1a45458

File tree

1 file changed

+49
-30
lines changed

1 file changed

+49
-30
lines changed

‎src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java‎

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /