diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BasicProxyFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BasicProxyFactoryImpl.java index 46ba636b43..eae143eb67 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BasicProxyFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BasicProxyFactoryImpl.java @@ -20,10 +20,6 @@ import net.bytebuddy.NamingStrategy; import net.bytebuddy.TypeCache; import net.bytebuddy.description.modifier.Visibility; import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy; -import net.bytebuddy.implementation.FieldAccessor; -import net.bytebuddy.implementation.MethodDelegation; -import net.bytebuddy.implementation.bytecode.assign.Assigner; -import net.bytebuddy.matcher.ElementMatchers; public class BasicProxyFactoryImpl implements BasicProxyFactory { @@ -47,10 +43,10 @@ public class BasicProxyFactoryImpl implements BasicProxyFactory { .subclass( superClass == null ? Object.class : superClass, ConstructorStrategy.Default.DEFAULT_CONSTRUCTOR ) .implement( interfaces == null ? NO_INTERFACES : interfaces ) .defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE ) - .method( ElementMatchers.isVirtual().and( ElementMatchers.not( ElementMatchers.isFinalizer() ) ) ) - .intercept( MethodDelegation.to( ProxyConfiguration.InterceptorDispatcher.class ) ) + .method( byteBuddyState.getProxyDefinitionHelpers().getVirtualNotFinalizerFilter() ) + .intercept( byteBuddyState.getProxyDefinitionHelpers().getDelegateToInterceptorDispatcherMethodDelegation() ) .implement( ProxyConfiguration.class ) - .intercept( FieldAccessor.ofField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME ).withAssigner( Assigner.DEFAULT, Assigner.Typing.DYNAMIC ) ) + .intercept( byteBuddyState.getProxyDefinitionHelpers().getInterceptorFieldAccessor() ) ); this.interceptor = new PassThroughInterceptor( proxyClass.getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java index 3acdf37439..0c46420472 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java @@ -6,6 +6,13 @@ */ package org.hibernate.bytecode.internal.bytebuddy; +import static net.bytebuddy.matcher.ElementMatchers.isFinalizer; +import static net.bytebuddy.matcher.ElementMatchers.isSynthetic; +import static net.bytebuddy.matcher.ElementMatchers.isVirtual; +import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.not; +import static net.bytebuddy.matcher.ElementMatchers.returns; import static org.hibernate.internal.CoreLogging.messageLogger; import java.io.File; @@ -20,17 +27,23 @@ import java.util.function.Function; import org.hibernate.HibernateException; import org.hibernate.bytecode.spi.BasicProxyFactory; import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.proxy.ProxyConfiguration; import org.hibernate.proxy.ProxyFactory; import net.bytebuddy.ByteBuddy; import net.bytebuddy.TypeCache; import net.bytebuddy.asm.AsmVisitorWrapper.ForDeclaredMethods; import net.bytebuddy.asm.MemberSubstitution; +import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.DynamicType.Unloaded; import net.bytebuddy.dynamic.loading.ClassInjector; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.dynamic.scaffold.TypeValidation; +import net.bytebuddy.implementation.FieldAccessor; +import net.bytebuddy.implementation.MethodDelegation; +import net.bytebuddy.implementation.bytecode.assign.Assigner; +import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.pool.TypePool; @@ -52,6 +65,8 @@ public final class ByteBuddyState { private final ForDeclaredMethods getDeclaredMethodMemberSubstitution; private final ForDeclaredMethods getMethodMemberSubstitution; + private final ProxyDefinitionHelpers proxyDefinitionHelpers; + /** * It will be easier to maintain the cache and its state when it will no longer be static * in Hibernate ORM 6+. @@ -75,6 +90,8 @@ public final class ByteBuddyState { this.getDeclaredMethodMemberSubstitution = null; this.getMethodMemberSubstitution = null; } + + this.proxyDefinitionHelpers = new ProxyDefinitionHelpers(); } /** @@ -135,6 +152,17 @@ public final class ByteBuddyState { return make( typePool, builder ).getBytes(); } + /** + * Returns the proxy definition helpers to reuse when defining proxies. + *
+ * These elements are shared as they are immutable.
+ *
+ * @return The proxy definition helpers.
+ */
+ public ProxyDefinitionHelpers getProxyDefinitionHelpers() {
+ return proxyDefinitionHelpers;
+ }
+
/**
* Wipes out all known caches used by ByteBuddy. This implies it might trigger the need
* to re-create some helpers if used at runtime, especially as this state is shared by
@@ -276,4 +304,47 @@ public final class ByteBuddyState {
}
}
}
+
+ /**
+ * Shared proxy definition helpers. They are immutable so we can safely share them.
+ */
+ public static class ProxyDefinitionHelpers {
+
+ private final ElementMatcher super MethodDescription> groovyGetMetaClassFilter;
+ private final ElementMatcher super MethodDescription> virtualNotFinalizerFilter;
+ private final ElementMatcher super MethodDescription> hibernateGeneratedMethodFilter;
+ private final MethodDelegation delegateToInterceptorDispatcherMethodDelegation;
+ private final FieldAccessor.PropertyConfigurable interceptorFieldAccessor;
+
+ private ProxyDefinitionHelpers() {
+ this.groovyGetMetaClassFilter = isSynthetic().and( named( "getMetaClass" )
+ .and( returns( td -> "groovy.lang.MetaClass".equals( td.getName() ) ) ) );
+ this.virtualNotFinalizerFilter = isVirtual().and( not( isFinalizer() ) );
+ this.hibernateGeneratedMethodFilter = nameStartsWith( "$$_hibernate_" ).and( isVirtual() );
+ this.delegateToInterceptorDispatcherMethodDelegation = MethodDelegation
+ .to( ProxyConfiguration.InterceptorDispatcher.class );
+ this.interceptorFieldAccessor = FieldAccessor.ofField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME )
+ .withAssigner( Assigner.DEFAULT, Assigner.Typing.DYNAMIC );
+ }
+
+ public ElementMatcher super MethodDescription> getGroovyGetMetaClassFilter() {
+ return groovyGetMetaClassFilter;
+ }
+
+ public ElementMatcher super MethodDescription> getVirtualNotFinalizerFilter() {
+ return virtualNotFinalizerFilter;
+ }
+
+ public ElementMatcher super MethodDescription> getHibernateGeneratedMethodFilter() {
+ return hibernateGeneratedMethodFilter;
+ }
+
+ public MethodDelegation getDelegateToInterceptorDispatcherMethodDelegation() {
+ return delegateToInterceptorDispatcherMethodDelegation;
+ }
+
+ public FieldAccessor.PropertyConfigurable getInterceptorFieldAccessor() {
+ return interceptorFieldAccessor;
+ }
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/proxy/pojo/bytebuddy/ByteBuddyProxyHelper.java b/hibernate-core/src/main/java/org/hibernate/proxy/pojo/bytebuddy/ByteBuddyProxyHelper.java
index f94cf4b943..2e3d5fdef5 100644
--- a/hibernate-core/src/main/java/org/hibernate/proxy/pojo/bytebuddy/ByteBuddyProxyHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/proxy/pojo/bytebuddy/ByteBuddyProxyHelper.java
@@ -6,17 +6,8 @@
*/
package org.hibernate.proxy.pojo.bytebuddy;
-import static net.bytebuddy.matcher.ElementMatchers.isFinalizer;
-import static net.bytebuddy.matcher.ElementMatchers.isSynthetic;
-import static net.bytebuddy.matcher.ElementMatchers.isVirtual;
-import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.not;
-import static net.bytebuddy.matcher.ElementMatchers.returns;
import static org.hibernate.internal.CoreLogging.messageLogger;
-import java.io.File;
-import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
@@ -28,24 +19,16 @@ import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.bytecode.internal.bytebuddy.ByteBuddyState;
import org.hibernate.cfg.Environment;
-import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
-import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.ProxyConfiguration;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.type.CompositeType;
import net.bytebuddy.NamingStrategy;
import net.bytebuddy.TypeCache;
import net.bytebuddy.description.modifier.Visibility;
-import net.bytebuddy.dynamic.DynamicType.Unloaded;
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
-import net.bytebuddy.implementation.FieldAccessor;
-import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
-import net.bytebuddy.implementation.bytecode.assign.Assigner;
public class ByteBuddyProxyHelper implements Serializable {
@@ -69,17 +52,17 @@ public class ByteBuddyProxyHelper implements Serializable {
key.addAll( Arrays.