From d13ecfc8f57cd1279643fe5ff057aa99db5d3ef6 Mon Sep 17 00:00:00 2001 From: Andi Huber Date: Mon, 11 Nov 2024 10:30:51 +0100 Subject: [PATCH] CAUSEWAY-2297: optimization: check for internal bean semantics directly in _ClassCache --- commons/src/main/java/module-info.java | 1 + .../internal/annotations}/BeanInternal.java | 3 +- .../internal/reflection/_ClassCache.java | 69 +++++++++++++++---- .../CausewayBeanFactoryPostProcessor.java | 3 +- .../beans/CausewayBeanTypeClassifier.java | 7 +- .../beans/CausewayBeanTypeRegistry.java | 2 + .../beans/JdoBeanTypeClassifier.java | 2 + 7 files changed, 65 insertions(+), 22 deletions(-) rename {core/config/src/main/java/org/apache/causeway/core/config/beans => commons/src/main/java/org/apache/causeway/commons/internal/annotations}/BeanInternal.java (96%) diff --git a/commons/src/main/java/module-info.java b/commons/src/main/java/module-info.java index 0d6f76e58a0..2296e97a465 100644 --- a/commons/src/main/java/module-info.java +++ b/commons/src/main/java/module-info.java @@ -29,6 +29,7 @@ exports org.apache.causeway.commons.tabular; // internals exported as well exports org.apache.causeway.commons.internal; + exports org.apache.causeway.commons.internal.annotations; exports org.apache.causeway.commons.internal.assertions; exports org.apache.causeway.commons.internal.base; exports org.apache.causeway.commons.internal.binding; diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/BeanInternal.java b/commons/src/main/java/org/apache/causeway/commons/internal/annotations/BeanInternal.java similarity index 96% rename from core/config/src/main/java/org/apache/causeway/core/config/beans/BeanInternal.java rename to commons/src/main/java/org/apache/causeway/commons/internal/annotations/BeanInternal.java index 035a505cbc1..ca7e453477e 100644 --- a/core/config/src/main/java/org/apache/causeway/core/config/beans/BeanInternal.java +++ b/commons/src/main/java/org/apache/causeway/commons/internal/annotations/BeanInternal.java @@ -16,8 +16,7 @@ * specific language governing permissions and limitations * under the License. */ - -package org.apache.causeway.core.config.beans; +package org.apache.causeway.commons.internal.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java b/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java index 81c76f67cbe..a6255f54bf3 100644 --- a/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java +++ b/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java @@ -22,6 +22,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -35,12 +36,14 @@ import jakarta.xml.bind.annotation.XmlRootElement; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; import org.springframework.lang.Nullable; import org.springframework.util.ReflectionUtils; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.functional.Try; import org.apache.causeway.commons.internal._Constants; +import org.apache.causeway.commons.internal.annotations.BeanInternal; import org.apache.causeway.commons.internal.base._Casts; import org.apache.causeway.commons.internal.base._NullSafe; import org.apache.causeway.commons.internal.base._Strings; @@ -100,6 +103,13 @@ public void add(final Class type) { public boolean hasJaxbRootElementSemantics(final Class type) { return classModel(type).hasJaxbRootElementSemantics; } + + /** + * whether type is annotated with {@link BeanInternal} or {@link Configuration} + */ + public boolean hasInternalBeanSemantics(final Class type) { + return classModel(type).hasInternalBeanSemantics; + } /** * whether type is annotated with {@link Named} @@ -248,21 +258,44 @@ public Optional lookupAttribute( // -- IMPLEMENATION DETAILS - @RequiredArgsConstructor - private static class ClassModel { - private final Can declaredFields; - private final boolean hasJaxbRootElementSemantics; - private final boolean isAnnotatedWithNamed; - - private final Map publicConstructorsByKey = new HashMap<>(); - private final Map constructorsWithInjectSemanticsByKey = new HashMap<>(); - - private final Map resolvedMethodsByKey = new HashMap<>(); - private final Map publicMethodsByKey = new HashMap<>(); - private final Map postConstructMethodsByKey = new HashMap<>(); - - private final Map> declaredMethodsByAttribute = new HashMap<>(); - private final Map attributeMap = new ConcurrentHashMap<>(); + private record ClassModel(Can declaredFields, + boolean hasInternalBeanSemantics, + boolean hasJaxbRootElementSemantics, + boolean isAnnotatedWithNamed, + + Map publicConstructorsByKey, + Map constructorsWithInjectSemanticsByKey, + + Map resolvedMethodsByKey, + Map publicMethodsByKey, + Map postConstructMethodsByKey, + + Map> declaredMethodsByAttribute, + Map attributeMap + ) { + + ClassModel(Can declaredFields, + boolean hasInternalBeanSemantics, + boolean hasJaxbRootElementSemantics, + boolean isAnnotatedWithNamed) { + this(declaredFields, hasInternalBeanSemantics, hasJaxbRootElementSemantics, isAnnotatedWithNamed, + new HashMap<>(), + new HashMap<>(), + new HashMap<>(), + new HashMap<>(), + new HashMap<>(), + new HashMap<>(), + new ConcurrentHashMap<>()); + } + + public static ClassModel INTERNAL = new ClassModel(Can.empty(), true, false, false, + Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), + Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), + Collections.emptyMap()); + + public static ClassModel internal() { + return INTERNAL; + } } private final Map, ClassModel> inspectedTypes = new HashMap<>(); @@ -349,8 +382,14 @@ private ClassModel inspectType(final Class _type) { // }) // .collect(Can.toCan()); + var hasInternalBeanSemantics = _Annotations.isPresent(type, Configuration.class) + || _Annotations.isPresent(type, BeanInternal.class); + + if(hasInternalBeanSemantics) return ClassModel.internal(); //skip further inspection + var model = new ClassModel( Can.ofArray(type.getDeclaredFields()), + hasInternalBeanSemantics, _Annotations.isPresent(type, XmlRootElement.class), _Annotations.isPresent(type, Named.class)); diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanFactoryPostProcessor.java b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanFactoryPostProcessor.java index 1592c48b2b1..d31888f7152 100644 --- a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanFactoryPostProcessor.java +++ b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanFactoryPostProcessor.java @@ -30,6 +30,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.stereotype.Component; @@ -54,7 +55,7 @@ * @since 2.0 * */ -@Component +@Configuration(proxyBeanMethods = false) @Named(CausewayModuleCoreConfig.NAMESPACE + ".CausewayBeanFactoryPostProcessor") @Import({ AopPatch.class diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifier.java b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifier.java index eb3b55bf92c..df7d6082049 100644 --- a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifier.java +++ b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifier.java @@ -35,6 +35,7 @@ import org.apache.causeway.applib.id.LogicalType; import org.apache.causeway.applib.services.metamodel.BeanSort; import org.apache.causeway.commons.collections.Can; +import org.apache.causeway.commons.internal.annotations.BeanInternal; import org.apache.causeway.commons.internal.context._Context; import org.apache.causeway.commons.internal.reflection._Annotations; import org.apache.causeway.commons.internal.reflection._ClassCache; @@ -129,10 +130,8 @@ public CausewayBeanMetaData classify(final @NonNull Class type) { // handle internal bean types ... - var aBeanInternal = _Annotations.synthesize(type, BeanInternal.class); - if(aBeanInternal.isPresent()) { - var logicalType = LogicalType.infer(type); - Attributes.HAS_DOMAIN_SERVICE_SEMANTICS.set(classCache, type, "true"); + if(classCache.hasInternalBeanSemantics(type)) { + var logicalType = LogicalType.infer(type); //TODO should be deprecated in favor of Spring provided bean names return CausewayBeanMetaData.injectable(BeanSort.MANAGED_BEAN_NOT_CONTRIBUTING, logicalType); } diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeRegistry.java b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeRegistry.java index 33668e15020..1f140c16b38 100644 --- a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeRegistry.java +++ b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeRegistry.java @@ -26,12 +26,14 @@ import java.util.stream.Stream; import org.apache.causeway.commons.collections.Can; +import org.apache.causeway.commons.internal.annotations.BeanInternal; import lombok.NonNull; /** * Holds discovered domain types grouped by bean-sort. */ +@BeanInternal public class CausewayBeanTypeRegistry { /** diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/beans/JdoBeanTypeClassifier.java b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/beans/JdoBeanTypeClassifier.java index 798badc8978..861ce77dd53 100644 --- a/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/beans/JdoBeanTypeClassifier.java +++ b/persistence/jdo/metamodel/src/main/java/org/apache/causeway/persistence/jdo/metamodel/beans/JdoBeanTypeClassifier.java @@ -23,6 +23,7 @@ import javax.jdo.annotations.EmbeddedOnly; import org.apache.causeway.applib.id.LogicalType; +import org.apache.causeway.commons.internal.annotations.BeanInternal; import org.apache.causeway.commons.internal.base._Strings; import org.apache.causeway.commons.internal.reflection._Annotations; import org.apache.causeway.core.config.beans.CausewayBeanMetaData; @@ -33,6 +34,7 @@ * ServiceLoader plugin, classifies PersistenceCapable types into BeanSort.ENTITY. * @since 2.0 */ +@BeanInternal public class JdoBeanTypeClassifier implements CausewayBeanTypeClassifierSpi { @Override