You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2019/10/10 11:54:59 UTC

[isis] branch v2 updated: ISIS-2158: further regarding terminology

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/v2 by this push:
     new 5d0f47e  ISIS-2158: further regarding terminology
5d0f47e is described below

commit 5d0f47e287583a2f182779cac1f29e024e663d58
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Oct 10 13:54:49 2019 +0200

    ISIS-2158: further regarding terminology
    
    - also consolidate some of the type categorization logic
    - a ManagedBeanAdapter is always of BeanSort = MANAGED_BEAN, so field
    removed
---
 .../applib/services/registry/ServiceRegistry.java  | 11 +---
 .../commons/internal/ioc/ManagedBeanAdapter.java   |  1 -
 .../commons/internal/ioc/cdi/BeanAdapterCDI.java   |  4 +-
 .../apache/isis/commons/internal/ioc/cdi/_CDI.java | 12 +---
 .../internal/ioc/spring/BeanAdapterSpring.java     |  5 +-
 .../isis/commons/internal/ioc/spring/_Spring.java  |  8 +--
 .../IsisBeanFactoryPostProcessorForSpring.java     | 39 +++---------
 .../beans/IsisComponentScanInterceptor.java}       | 48 ++++-----------
 .../isis/config/registry/IsisBeanTypeRegistry.java | 69 +++++++++++++++-------
 .../apache/isis/config/registry/TypeMetaData.java  |  8 ++-
 .../isis/metamodel/MetaModelContext_usingCDI.java  |  3 +-
 .../metamodel/MetaModelContext_usingSpring.java    | 21 ++++---
 .../isis/metamodel/ServiceRegistry_forTesting.java |  3 -
 .../ApplicationFeatureRepositoryDefault.java       |  5 +-
 .../services/registry/ServiceRegistryDefault.java  | 34 ++++-------
 .../specloader/SpecificationLoaderDefault.java     |  1 -
 .../specimpl/ObjectSpecificationAbstract.java      |  8 +--
 .../specloader/validator/ValidationFailures.java   |  2 +-
 .../homepage/HomePageResolverServiceDefault.java   |  3 +-
 .../persistence/adapter/ObjectAdapterForBean.java  |  4 +-
 .../ObjectAdapterContext_ServiceLookup.java        |  6 +-
 .../ObjectAdapterMementoSupportUsingSpring.java    |  2 +-
 .../bootstrapping/builtin-singleton.list           |  2 +-
 23 files changed, 121 insertions(+), 178 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/registry/ServiceRegistry.java b/core/applib/src/main/java/org/apache/isis/applib/services/registry/ServiceRegistry.java
index 75de9ab..7d16343 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/registry/ServiceRegistry.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/registry/ServiceRegistry.java
@@ -32,7 +32,6 @@ import org.apache.isis.commons.internal._Constants;
 import org.apache.isis.commons.internal.base._Reduction;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
-import org.apache.isis.commons.internal.ioc.BeanSort;
 import org.apache.isis.commons.internal.ioc.spring._Spring;
 import org.apache.isis.commons.internal.reflection._Reflect;
 
@@ -81,14 +80,6 @@ public interface ServiceRegistry {
     }
 
     /**
-     * Streams all bean adapters of given BeanSort.
-     */
-    default Stream<ManagedBeanAdapter> streamRegisteredBeansOfSort(BeanSort sort) {
-        return streamRegisteredBeans()
-                .filter(beanAdapter->beanAdapter.getManagedObjectSort()==sort);
-    }
-
-    /**
      * Returns all bean adapters that have been registered.
      */
     public Stream<ManagedBeanAdapter> streamRegisteredBeans();
@@ -101,7 +92,7 @@ public interface ServiceRegistry {
     public Optional<ManagedBeanAdapter> lookupRegisteredBeanById(String id);
 
 
-    public default ManagedBeanAdapter lookupRegisteredBeanByNameElseFail(String id) {
+    public default ManagedBeanAdapter lookupManagedBeanByNameElseFail(String id) {
         return lookupRegisteredBeanById(id).orElseThrow(
                 ()->_Exceptions.unrecoverable(
                         "Failed to lookup BeanAdapter by id '" + id + "'")); 
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/ManagedBeanAdapter.java b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/ManagedBeanAdapter.java
index b1c185f..af52e81 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/ManagedBeanAdapter.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/ManagedBeanAdapter.java
@@ -28,7 +28,6 @@ public interface ManagedBeanAdapter {
     String getId();
     Bin<?> getInstance();
     Class<?> getBeanClass();
-    BeanSort getManagedObjectSort();
 
     boolean isCandidateFor(Class<?> requiredType);
 
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/cdi/BeanAdapterCDI.java b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/cdi/BeanAdapterCDI.java
index 82fb374..c53913c 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/cdi/BeanAdapterCDI.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/cdi/BeanAdapterCDI.java
@@ -21,9 +21,8 @@ package org.apache.isis.commons.internal.ioc.cdi;
 import javax.enterprise.inject.spi.Bean;
 
 import org.apache.isis.commons.collections.Bin;
-import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
-import org.apache.isis.commons.internal.ioc.BeanSort;
 import org.apache.isis.commons.internal.ioc.LifecycleContext;
+import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
 
 import lombok.Value;
 import lombok.val;
@@ -34,7 +33,6 @@ final class BeanAdapterCDI implements ManagedBeanAdapter {
     private final String id;
     private final LifecycleContext lifecycleContext;
     private final Bean<?> bean;
-    private final BeanSort managedObjectSort;
 
     @Override
     public Bin<?> getInstance() {
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/cdi/_CDI.java b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/cdi/_CDI.java
index e36564d..14551f1 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/cdi/_CDI.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/cdi/_CDI.java
@@ -42,9 +42,8 @@ import org.apache.isis.commons.collections.Bin;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.commons.internal.functions._Functions.CheckedRunnable;
-import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
-import org.apache.isis.commons.internal.ioc.BeanSort;
 import org.apache.isis.commons.internal.ioc.LifecycleContext;
+import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
 
 import static org.apache.isis.commons.internal.base._NullSafe.isEmpty;
 import static org.apache.isis.commons.internal.base._NullSafe.stream;
@@ -199,7 +198,6 @@ public final class _CDI {
          * @param beanNameProvider - usually ServiceUtil::idOfBean
          */
         public static Stream<ManagedBeanAdapter> streamAllBeans(
-                Function<Class<?>, BeanSort> classifier, 
                 Function<Bean<?>, String> beanNameProvider) {
 
             return streamAllCDIBeans()
@@ -207,14 +205,8 @@ public final class _CDI {
 
                         val scope = bean.getScope().getSimpleName(); // also works for produced beans
                         val lifecycleContext = LifecycleContext.valueOf(scope);
-
-                        // getBeanClass() does not work for produced beans as intended here! 
-                        // (we do get the producer's class instead)
-                        val type = bean.getBeanClass(); 
-                        val sort = classifier.apply(type);
-
                         val id = beanNameProvider.apply(bean);
-                        val beanAdapter = BeanAdapterCDI.of(id, lifecycleContext, bean, sort);
+                        val beanAdapter = BeanAdapterCDI.of(id, lifecycleContext, bean);
                         return beanAdapter;
                     });
 
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/spring/BeanAdapterSpring.java b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/spring/BeanAdapterSpring.java
index b8cd977..c266c0f 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/spring/BeanAdapterSpring.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/spring/BeanAdapterSpring.java
@@ -21,9 +21,8 @@ package org.apache.isis.commons.internal.ioc.spring;
 import org.springframework.beans.factory.ObjectProvider;
 
 import org.apache.isis.commons.collections.Bin;
-import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
-import org.apache.isis.commons.internal.ioc.BeanSort;
 import org.apache.isis.commons.internal.ioc.LifecycleContext;
+import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
 
 import lombok.Value;
 import lombok.val;
@@ -35,7 +34,7 @@ final class BeanAdapterSpring implements ManagedBeanAdapter {
     private final LifecycleContext lifecycleContext;
     private final Class<?> beanClass;
     private final ObjectProvider<?> beanProvider;
-    private final BeanSort managedObjectSort;
+    //private final BeanSort managedObjectSort;
 
     @Override
     public Bin<?> getInstance() {
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/spring/_Spring.java b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/spring/_Spring.java
index b8d9dc4..c38c078 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/spring/_Spring.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/spring/_Spring.java
@@ -49,9 +49,8 @@ import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.collections._Sets;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
-import org.apache.isis.commons.internal.ioc.ScannedTypeClassifier;
 import org.apache.isis.commons.internal.ioc.LifecycleContext;
+import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
 
 import static org.apache.isis.commons.internal.base._NullSafe.stream;
 import static org.apache.isis.commons.internal.base._With.requires;
@@ -124,7 +123,7 @@ public class _Spring {
      * @param classifier
      * @return
      */
-    public static Stream<ManagedBeanAdapter> streamAllBeans(ScannedTypeClassifier classifier) {
+    public static Stream<ManagedBeanAdapter> streamAllBeans() {
 
         val context = context();
         val beanFactory = ((ConfigurableApplicationContext)context).getBeanFactory();
@@ -133,7 +132,6 @@ public class _Spring {
                 .map(name->{
 
                     val type = context.getType(name);
-                    val managedObjectSort = classifier.quickClassify(type);
                     val id = name; // just reuse the bean's name
 
                     val scope = beanFactory.getBeanDefinition(name).getScope();
@@ -142,7 +140,7 @@ public class _Spring {
                     val resolvableType = ResolvableType.forClass(type);
                     val bean = context.getBeanProvider(resolvableType);
 
-                    val beanAdapter = BeanAdapterSpring.of(id, lifecycleContext, type, bean, managedObjectSort);
+                    val beanAdapter = BeanAdapterSpring.of(id, lifecycleContext, type, bean);
 
                     return beanAdapter;
                 });
diff --git a/core/config/src/main/java/org/apache/isis/config/beans/IsisBeanFactoryPostProcessorForSpring.java b/core/config/src/main/java/org/apache/isis/config/beans/IsisBeanFactoryPostProcessorForSpring.java
index d5f68e3..c4d6181 100644
--- a/core/config/src/main/java/org/apache/isis/config/beans/IsisBeanFactoryPostProcessorForSpring.java
+++ b/core/config/src/main/java/org/apache/isis/config/beans/IsisBeanFactoryPostProcessorForSpring.java
@@ -26,14 +26,10 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.Mixin;
 import org.apache.isis.applib.annotation.ViewModel;
-import org.apache.isis.commons.internal.reflection._Annotations;
 import org.apache.isis.config.registry.IsisBeanTypeRegistry;
 import org.apache.isis.config.registry.TypeMetaData;
 
-import static org.apache.isis.commons.internal.reflection._Annotations.findNearestAnnotation;
-
 import lombok.Getter;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
@@ -53,12 +49,14 @@ import lombok.extern.log4j.Log4j2;
 public class IsisBeanFactoryPostProcessorForSpring implements BeanFactoryPostProcessor {
 
     @Getter(lazy=true) 
-    private final IsisBeanTypeRegistry typeRegistry = IsisBeanTypeRegistry.current();
+    private final IsisComponentScanInterceptor interceptor = IsisBeanTypeRegistry.current();
     
     @Override
     public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
         
         val registry = (BeanDefinitionRegistry) beanFactory;
+        val interceptor = getInterceptor();
+        
         for (String beanDefinitionName : registry.getBeanDefinitionNames()) {
             
             log.debug(()->"processing: " + beanDefinitionName);
@@ -73,10 +71,9 @@ public class IsisBeanFactoryPostProcessorForSpring implements BeanFactoryPostPro
             
             val typeMetaData = TypeMetaData.of(beanDefinition.getBeanClassName());
             
-            //TODO should re-implement/rename this method 
-            getTypeRegistry().isIoCManagedType(typeMetaData);
-             
-            if(hasMetamodelAnnotation_otherThanDomainService(typeMetaData)) {
+            val injectable = interceptor.isInjectable(typeMetaData);
+            
+            if(!injectable) {
                 registry.removeBeanDefinition(beanDefinitionName);
                 log.debug(()->"removing: " + beanDefinitionName);
             }
@@ -84,28 +81,6 @@ public class IsisBeanFactoryPostProcessorForSpring implements BeanFactoryPostPro
         }
         
     }
-    
-    //TODO this should be a functionality of the IsisBeanTypeRegistry
-    private boolean hasMetamodelAnnotation_otherThanDomainService(TypeMetaData typeMetaData) {
-        
-        val type = typeMetaData.getUnderlyingClass();
-        
-        
-        if(findNearestAnnotation(type, DomainObject.class).isPresent()) {
-            return true;
-        }
-        
-        if(findNearestAnnotation(type, ViewModel.class).isPresent()) {
-            return true;
-        }
-        
-        if(findNearestAnnotation(type, Mixin.class).isPresent()) {
-            return true;
-        }
-        
-        
-        return false;
-        
-    }
+
 
 }
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/ScannedTypeClassifier.java b/core/config/src/main/java/org/apache/isis/config/beans/IsisComponentScanInterceptor.java
similarity index 53%
rename from core/commons/src/main/java/org/apache/isis/commons/internal/ioc/ScannedTypeClassifier.java
rename to core/config/src/main/java/org/apache/isis/config/beans/IsisComponentScanInterceptor.java
index c1bb08d..5a0b52a 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/ioc/ScannedTypeClassifier.java
+++ b/core/config/src/main/java/org/apache/isis/config/beans/IsisComponentScanInterceptor.java
@@ -16,7 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.commons.internal.ioc;
+package org.apache.isis.config.beans;
+
+import org.springframework.stereotype.Component;
+
+import org.apache.isis.config.registry.TypeMetaData;
 
 /**
  * @apiNote implementing classes must not rely on IsisConfiguration or other provisioned 
@@ -24,50 +28,22 @@ package org.apache.isis.commons.internal.ioc;
  * 
  * @since 2.0 
  */
-public interface ScannedTypeClassifier {
-
-    BeanSort quickClassify(Class<?> type);
+public interface IsisComponentScanInterceptor {
 
     /**
-     * Whether given type is available for injection.
-     * 
+     * Whether given {@link Component} annotated or meta-annotated type should be made
+     * available for injection.
      * @param type
-     * @return
+     * @apiNote implementing classes might have side effects, eg. intercept 
+     * discovered types into a type registry
      */
-    default boolean isInjectable(Class<?> type) {
-        return quickClassify(type) == BeanSort.MANAGED_BEAN;
-    }
+    boolean isInjectable(TypeMetaData type);
 
     /**
-     * Whether given type is to be introspected by the framework.
-     * 
-     * @param type
-     * @return
-     */
-    default boolean isIntrospectable(Class<?> type) {
-        return quickClassify(type) != BeanSort.UNKNOWN;
-    }
-    
-    // -- SYNONYMS
-    
-    /**
      * Whether given type is available for injection. Is a <em>Managed Bean</em>. 
-     * <p> synonym for {@link #isInjectable(Class)}
      * @param type
      * @return 
      */
-    default boolean isManagedBean(Class<?> type) {
-        return isInjectable(type);
-    }
-
-    /**
-     * Whether given type is to be introspected by the framework. Is a <em>Managed Object</em>. 
-     * <p> synonym for {@link #isIntrospectable(Class)}
-     * @param type
-     * @return
-     */
-    default boolean isManagedObject(Class<?> type) {
-        return isIntrospectable(type);
-    }
+    boolean isManagedBean(Class<?> type);
     
 }
diff --git a/core/config/src/main/java/org/apache/isis/config/registry/IsisBeanTypeRegistry.java b/core/config/src/main/java/org/apache/isis/config/registry/IsisBeanTypeRegistry.java
index 1389eee..9b73b0d 100644
--- a/core/config/src/main/java/org/apache/isis/config/registry/IsisBeanTypeRegistry.java
+++ b/core/config/src/main/java/org/apache/isis/config/registry/IsisBeanTypeRegistry.java
@@ -27,12 +27,9 @@ import java.util.Map;
 import java.util.Set;
 import java.util.stream.Stream;
 
-import javax.enterprise.context.RequestScoped;
 import javax.enterprise.inject.Vetoed;
-import javax.inject.Singleton;
 
 import org.springframework.stereotype.Component;
-import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainService;
@@ -44,9 +41,9 @@ import org.apache.isis.commons.internal.components.SessionScopedComponent;
 import org.apache.isis.commons.internal.components.TransactionScopedComponent;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.commons.internal.ioc.BeanSort;
-import org.apache.isis.commons.internal.ioc.ScannedTypeClassifier;
 import org.apache.isis.commons.internal.ioc.spring._Spring;
 import org.apache.isis.commons.internal.reflection._Reflect;
+import org.apache.isis.config.beans.IsisComponentScanInterceptor;
 
 import static org.apache.isis.commons.internal.base._With.requires;
 import static org.apache.isis.commons.internal.reflection._Annotations.findNearestAnnotation;
@@ -62,7 +59,7 @@ import lombok.extern.log4j.Log4j2;
  * @since 2.0
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE) @Log4j2
-public final class IsisBeanTypeRegistry implements ScannedTypeClassifier, AutoCloseable {
+public final class IsisBeanTypeRegistry implements IsisComponentScanInterceptor, AutoCloseable {
 
     public static IsisBeanTypeRegistry current() {
         return _Context.computeIfAbsent(IsisBeanTypeRegistry.class, IsisBeanTypeRegistry::new);
@@ -157,11 +154,44 @@ public final class IsisBeanTypeRegistry implements ScannedTypeClassifier, AutoCl
 
     // -- FILTER
 
+    @Override
+    public boolean isInjectable(TypeMetaData typeMeta) {
+        
+        val type = typeMeta.getUnderlyingClass();
+        
+        intercept(type);
+        
+        if(findNearestAnnotation(type, DomainObject.class).isPresent()) {
+            return false; // reject
+        }
+        
+        if(findNearestAnnotation(type, ViewModel.class).isPresent()) {
+            return false; // reject
+        }
+        
+        if(findNearestAnnotation(type, Mixin.class).isPresent()) {
+            return false; // reject
+        }
+        
+        if(findNearestAnnotation(type, Vetoed.class).isPresent()) {
+            return false; // reject
+        }
+        
+        return true;
+    }
+    
+    @Override
+    public boolean isManagedBean(Class<?> type) {
+        val beanSort = quickClassify(type);
+        return beanSort.isManagedBean();
+    }
+    
+    // -- HELPER
+    
     // don't categorize this early, instead push candidate classes onto a queue for 
     // later processing when the SpecLoader initializes.
-    public boolean isIoCManagedType(TypeMetaData typeMetaData) {
+    private void intercept(Class<?> type) {
 
-        val type = typeMetaData.getUnderlyingClass();
         val beanSort = quickClassify(type);
 
         if(beanSort.isEntity()) {
@@ -171,7 +201,7 @@ public final class IsisBeanTypeRegistry implements ScannedTypeClassifier, AutoCl
             entityTypes.add(type); 
         }
 
-        val isToBeProvisioned = beanSort.isManagedBean();
+        val isToBeRegistered = beanSort.isManagedBean();
         val isToBeInspected = !beanSort.isUnknown();
 
         if(isToBeInspected) {
@@ -179,27 +209,24 @@ public final class IsisBeanTypeRegistry implements ScannedTypeClassifier, AutoCl
         }
 
         if(log.isDebugEnabled()) {
-            if(isToBeInspected || isToBeProvisioned) {
+            if(isToBeInspected || isToBeRegistered) {
                 log.debug("{} {} [{}]",
-                        isToBeProvisioned ? "provision" : beanSort.isEntity() ? "entity" : "skip",
+                        isToBeRegistered ? "provision" : beanSort.isEntity() ? "entity" : "skip",
                                 type,
                                 beanSort.name());
             }
         }
 
-        return isToBeProvisioned;
-
     }
 
     // the SpecLoader does a better job at this
-    @Override
-    public BeanSort quickClassify(Class<?> type) {
+    private BeanSort quickClassify(Class<?> type) {
 
         requires(type, "type");
 
         
         if(findNearestAnnotation(type, Vetoed.class).isPresent()) {
-            return BeanSort.UNKNOWN; // exclude from provisioning
+            return BeanSort.UNKNOWN; // reject
         }
 
         if(Collection.class.isAssignableFrom(type)) {
@@ -235,11 +262,7 @@ public final class IsisBeanTypeRegistry implements ScannedTypeClassifier, AutoCl
                 if(org.apache.isis.applib.ViewModel.class.isAssignableFrom(type)) {
                     return BeanSort.VIEW_MODEL;
                 }
-                // fall through
-
-            default:
-                // continue
-                break; 
+                break; // fall through
             } 
         }
 
@@ -282,6 +305,12 @@ public final class IsisBeanTypeRegistry implements ScannedTypeClassifier, AutoCl
         return BeanSort.UNKNOWN;
     }
 
+
+    
+
+
+
+
     // if we ever want to ever implement an alternative solution to the autoclose hack above ...
     //    public IsisBeanTypeRegistry copy() {
     //        
diff --git a/core/config/src/main/java/org/apache/isis/config/registry/TypeMetaData.java b/core/config/src/main/java/org/apache/isis/config/registry/TypeMetaData.java
index b427ff1..02d4ee8 100644
--- a/core/config/src/main/java/org/apache/isis/config/registry/TypeMetaData.java
+++ b/core/config/src/main/java/org/apache/isis/config/registry/TypeMetaData.java
@@ -21,11 +21,12 @@ package org.apache.isis.config.registry;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 
+import lombok.Getter;
 import lombok.Value;
 import lombok.val;
 
 @Value(staticConstructor="of")
-public class TypeMetaData {
+public final class TypeMetaData {
 
     /**
      * Fully qualified name of the underlying class.
@@ -61,10 +62,13 @@ public class TypeMetaData {
     //        return annotationTypes.contains(viewModelAnnotation);
     //    }
 
+    @Getter(lazy=true)
+    final Class<?> underlyingClass = resolveClass();
+    
     /**
      * @return the underlying class of this TypeMetaData
      */
-    public Class<?> getUnderlyingClass() {
+    private Class<?> resolveClass() {
         try {
             return _Context.loadClass(className);
         } catch (ClassNotFoundException e) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/MetaModelContext_usingCDI.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/MetaModelContext_usingCDI.java
index ce917d4..3c7b0e4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/MetaModelContext_usingCDI.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/MetaModelContext_usingCDI.java
@@ -32,7 +32,6 @@ import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.applib.services.xactn.TransactionState;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.commons.internal.ioc.BeanSort;
 import org.apache.isis.commons.internal.ioc.cdi._CDI;
 import org.apache.isis.config.IsisConfiguration;
 import org.apache.isis.config.IsisConfigurationLegacy;
@@ -156,7 +155,7 @@ class MetaModelContext_usingCDI implements MetaModelContext {
 
         val objectAdapterProvider = getObjectAdapterProvider();
 
-        return getServiceRegistry().streamRegisteredBeansOfSort(BeanSort.MANAGED_BEAN)
+        return getServiceRegistry().streamRegisteredBeans()
                 .map(objectAdapterProvider::adapterForBean) 
                 .peek(serviceAdapter->{
                     val oid = serviceAdapter.getOid();
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/MetaModelContext_usingSpring.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/MetaModelContext_usingSpring.java
index 03a86dd..7fd534b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/MetaModelContext_usingSpring.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/MetaModelContext_usingSpring.java
@@ -156,21 +156,20 @@ class MetaModelContext_usingSpring implements MetaModelContext {
 
         val objectAdapterProvider = getObjectAdapterProvider();
 
-        return getServiceRegistry().streamRegisteredBeans()
-                .filter(registeredBean->!registeredBean.getManagedObjectSort().isUnknown())        
+        return getServiceRegistry()
+                .streamRegisteredBeans()
                 .map(objectAdapterProvider::adapterForBean) 
-                .peek(objectAdapter->{
-                    
-                    val oid = objectAdapter.getOid();
-                    if(oid.isTransient()) {
-                        val msg = "ObjectAdapter for 'Bean' is expected not to be 'transient' " + oid;
-                        throw _Exceptions.unrecoverable(msg);
-                    }
-                })
+                .peek(this::guardAgainsTransient)
                 .collect(Collectors.toMap(ServiceUtil::idOfAdapter, v->v, (o,n)->n, LinkedHashMap::new));
     }
 
-    // -------------------------------------------------------------------------------
+    private void guardAgainsTransient(ObjectAdapter objectAdapter) {
+        val oid = objectAdapter.getOid();
+        if(oid.isTransient()) {
+            val msg = "ObjectAdapter for 'Bean' is expected not to be 'transient' " + oid;
+            throw _Exceptions.unrecoverable(msg);
+        }
+    }
 
 
 }
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/ServiceRegistry_forTesting.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/ServiceRegistry_forTesting.java
index 1667d93..efc729e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/ServiceRegistry_forTesting.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/ServiceRegistry_forTesting.java
@@ -31,7 +31,6 @@ import org.apache.isis.commons.internal.collections._Sets;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
-import org.apache.isis.commons.internal.ioc.BeanSort;
 import org.apache.isis.commons.internal.ioc.spring._Spring;
 import org.apache.isis.config.registry.IsisBeanTypeRegistry;
 
@@ -117,7 +116,6 @@ class ServiceRegistry_forTesting implements ServiceRegistry {
         String id;
         Bin<?> instance;
         public Class<?> beanClass;
-        BeanSort managedObjectSort;
 
         @Override
         public boolean isCandidateFor(Class<?> requiredType) {
@@ -132,7 +130,6 @@ class ServiceRegistry_forTesting implements ServiceRegistry {
                 .id(singleton.getClass().getName())
                 .instance(Bin.ofSingleton(singleton))
                 .beanClass(singleton.getClass())
-                .managedObjectSort(beanSortClassifier.quickClassify(singleton.getClass()))
                 .build();
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
index 5bb950a..afe4ef6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
@@ -29,7 +29,6 @@ import java.util.stream.Collectors;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
-import org.apache.isis.config.IsisConfiguration;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.SemanticsOf;
@@ -41,7 +40,7 @@ import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
-import org.apache.isis.commons.internal.ioc.BeanSort;
+import org.apache.isis.config.IsisConfiguration;
 import org.apache.isis.metamodel.facetapi.FacetHolder;
 import org.apache.isis.metamodel.facets.SingleIntValueFacet;
 import org.apache.isis.metamodel.facets.all.hide.HiddenFacet;
@@ -545,7 +544,7 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
 
     private _Lazy<List<ManagedBeanAdapter>> registeredServices = _Lazy.threadSafe(()->{
         val registeredServices = 
-                serviceRegistry.streamRegisteredBeansOfSort(BeanSort.MANAGED_BEAN)
+                serviceRegistry.streamRegisteredBeans()
                 .collect(Collectors.toList());
         return registeredServices;
     });
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/services/registry/ServiceRegistryDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/registry/ServiceRegistryDefault.java
index b03f578..f6e0b8e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/services/registry/ServiceRegistryDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/services/registry/ServiceRegistryDefault.java
@@ -25,7 +25,6 @@ import java.util.stream.Stream;
 
 import javax.inject.Inject;
 
-import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
@@ -47,34 +46,34 @@ import lombok.val;
 @DomainService(nature = NatureOfService.DOMAIN)
 public final class ServiceRegistryDefault implements ServiceRegistry {
     
-    //XXX to enforce provisioning order, a depends-on relationship; 
+    //XXX to enforce provisioning order, this is a depends-on relationship! 
     // keep as long as IsisConfigurationLegacy is used 
     @Inject private IsisConfigurationLegacy isisConfigurationLegacy; 
-
+    
     @Override
     public Optional<ManagedBeanAdapter> lookupRegisteredBeanById(String id) {
-        return Optional.ofNullable(registeredBeansById.get().get(id));
+        return Optional.ofNullable(managedBeansById.get().get(id));
     }
 
     @Override
     public Stream<ManagedBeanAdapter> streamRegisteredBeans() {
-        return registeredBeansById.get().values().stream();
+        return managedBeansById.get().values().stream();
     }
 
     
     // -- HELPER
 
-    private final _Lazy<Map<String, ManagedBeanAdapter>> registeredBeansById = 
-            _Lazy.threadSafe(this::enumerateBeans);
-
-    private Map<String, ManagedBeanAdapter> enumerateBeans() {
+    private final _Lazy<Map<String, ManagedBeanAdapter>> managedBeansById = 
+            _Lazy.threadSafe(this::enumerateManagedBeans);
 
-        val beanSortClassifier = IsisBeanTypeRegistry.current();
+    private Map<String, ManagedBeanAdapter> enumerateManagedBeans() {
+        
+        val filter = IsisBeanTypeRegistry.current();
         val map = _Maps.<String, ManagedBeanAdapter>newHashMap();
 
-        _Spring.streamAllBeans(beanSortClassifier)
+        _Spring.streamAllBeans()
         .filter(_NullSafe::isPresent)
-        .filter(x->!x.getManagedObjectSort().isUnknown()) // do not register unknown sort
+        .filter(bean->filter.isManagedBean(bean.getBeanClass())) // do not register unknown sort
         .forEach(bean->{
             val id = extractObjectType(bean.getBeanClass()).orElse(bean.getId());
             map.put(id, bean);
@@ -83,7 +82,7 @@ public final class ServiceRegistryDefault implements ServiceRegistry {
         return map;
     }
 
-    //TODO[2112] this would be the responsibility of the specloader, but 
+    //TODO[2158] this would be the responsibility of the specloader, but 
     // for now we use as very simple approach
     private Optional<String> extractObjectType(Class<?> type) {
 
@@ -96,15 +95,6 @@ public final class ServiceRegistryDefault implements ServiceRegistry {
             return Optional.empty(); // stop processing
         }
 
-        val aDomainObject = _Reflect.getAnnotation(type, DomainObject.class);
-        if(aDomainObject!=null) {
-            val objectType = aDomainObject.objectType();
-            if(_Strings.isNotEmpty(objectType)) {
-                return Optional.of(objectType); 
-            }
-            return Optional.empty(); // stop processing
-        }
-
         return Optional.empty();
 
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java
index 12d9fd0..10b9efc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/SpecificationLoaderDefault.java
@@ -87,7 +87,6 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
     
     private final SpecificationCacheDefault<ObjectSpecification> cache = 
             new SpecificationCacheDefault<>();
-    
 
     /** JUnit Test Support */
     public static SpecificationLoaderDefault getInstance (
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index e377b99..69a454c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -768,8 +768,8 @@ public abstract class ObjectSpecificationAbstract extends FacetHolderImpl implem
 
 
 
-    private Stream<ManagedBeanAdapter> streamServiceBeans() {
-        return context.getServiceRegistry().streamRegisteredBeansOfSort(BeanSort.MANAGED_BEAN);
+    private Stream<ManagedBeanAdapter> streamManagedBeans() {
+        return context.getServiceRegistry().streamRegisteredBeans();
     }
 
     // -- CONTRIBUTEE ASSOCIATIONS (PROPERTIES AND COLLECTIONS)
@@ -779,7 +779,7 @@ public abstract class ObjectSpecificationAbstract extends FacetHolderImpl implem
             return Collections.emptyList();
         }
         val contributeeAssociations = _Lists.<ObjectAssociation>newArrayList();
-        streamServiceBeans()
+        streamManagedBeans()
         .forEach(serviceBean->forEachContributeeAssociation(serviceBean, contributeeAssociations::add));
         return contributeeAssociations;
     }
@@ -872,7 +872,7 @@ public abstract class ObjectSpecificationAbstract extends FacetHolderImpl implem
             return Collections.emptyList();
         }
         val contributeeActions = _Lists.<ObjectAction>newArrayList();
-        streamServiceBeans()
+        streamManagedBeans()
         .forEach(serviceBean->forEachContributeeAction(serviceBean, contributeeActions::add));
         return contributeeActions;
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/ValidationFailures.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/ValidationFailures.java
index 28c5517..8f26eb7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/ValidationFailures.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/specloader/validator/ValidationFailures.java
@@ -32,7 +32,7 @@ import lombok.val;
 public final class ValidationFailures implements Iterable<ValidationFailure> {
 
     
-    private final Set<ValidationFailure> failures = _Sets.newTreeSet();
+    private final Set<ValidationFailure> failures = _Sets.newConcurrentHashSet();
 
     public void add(Identifier origin, String pattern, Object... arguments) {
         val message = String.format(pattern, arguments);
diff --git a/core/runtime-services/src/main/java/org/apache/isis/runtime/services/homepage/HomePageResolverServiceDefault.java b/core/runtime-services/src/main/java/org/apache/isis/runtime/services/homepage/HomePageResolverServiceDefault.java
index 71418d0..3ccc1c2 100644
--- a/core/runtime-services/src/main/java/org/apache/isis/runtime/services/homepage/HomePageResolverServiceDefault.java
+++ b/core/runtime-services/src/main/java/org/apache/isis/runtime/services/homepage/HomePageResolverServiceDefault.java
@@ -32,7 +32,6 @@ import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.commons.internal.ioc.BeanSort;
 import org.apache.isis.config.registry.IsisBeanTypeRegistry;
 import org.apache.isis.metamodel.MetaModelContext;
 import org.apache.isis.metamodel.adapter.ObjectAdapter;
@@ -84,7 +83,7 @@ public class HomePageResolverServiceDefault implements HomePageResolverService {
         // -- 2) lookup managed beans that have actions annotated with @HomePage
 
         homePageAction = 
-                serviceRegistry.streamRegisteredBeansOfSort(BeanSort.MANAGED_BEAN)
+                serviceRegistry.streamRegisteredBeans()
                 .map(bean->bean.getBeanClass())
                 .map(managedBeanType->specLoader.loadSpecification(managedBeanType))
                 .filter(_NullSafe::isPresent)
diff --git a/core/runtime/src/main/java/org/apache/isis/runtime/persistence/adapter/ObjectAdapterForBean.java b/core/runtime/src/main/java/org/apache/isis/runtime/persistence/adapter/ObjectAdapterForBean.java
index 33e20e5..38cb2e2 100644
--- a/core/runtime/src/main/java/org/apache/isis/runtime/persistence/adapter/ObjectAdapterForBean.java
+++ b/core/runtime/src/main/java/org/apache/isis/runtime/persistence/adapter/ObjectAdapterForBean.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.runtime.persistence.adapter;
 
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.commons.internal.ioc.ManagedBeanAdapter;
 import org.apache.isis.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.metamodel.adapter.oid.Oid;
@@ -46,7 +47,8 @@ public class ObjectAdapterForBean implements ObjectAdapter {
 
     @Override
     public Object getPojo() {
-        return bean.getInstance().iterator().next();
+        return bean.getInstance().getFirst().orElseThrow(()->
+            _Exceptions.unrecoverable("This adapter should not even exist: spec=" + spec));
     }
 
     @Override
diff --git a/core/runtime/src/main/java/org/apache/isis/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java b/core/runtime/src/main/java/org/apache/isis/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
index b957235..098896f 100644
--- a/core/runtime/src/main/java/org/apache/isis/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
+++ b/core/runtime/src/main/java/org/apache/isis/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ServiceLookup.java
@@ -23,10 +23,8 @@ import java.util.Map;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.commons.internal.assertions._Assert;
 import org.apache.isis.commons.internal.base._Timing;
-import org.apache.isis.commons.internal.base._Timing.StopWatch;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.context._Context;
-import org.apache.isis.commons.internal.ioc.BeanSort;
 import org.apache.isis.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.metamodel.adapter.oid.RootOid;
 
@@ -88,12 +86,12 @@ class ObjectAdapterContext_ServiceLookup {
 
         objectAdapterContext.printContextInfo("INIT SERVICE ID LOOKUP RESOURCE");
 
-        StopWatch watch = _Timing.now();
+        val watch = _Timing.now();
 
         val servicesByIdResource = new ServicesByIdResource();
         val adapterProvider = objectAdapterContext.getObjectAdapterProvider();
 
-        serviceRegistry.streamRegisteredBeansOfSort(BeanSort.MANAGED_BEAN)
+        serviceRegistry.streamRegisteredBeans()
         .map(adapterProvider::adapterForBean)
         .forEach(serviceAdapter->{
             _Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
diff --git a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/memento/ObjectAdapterMementoSupportUsingSpring.java b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/memento/ObjectAdapterMementoSupportUsingSpring.java
index 018a850..f514f7f 100644
--- a/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/memento/ObjectAdapterMementoSupportUsingSpring.java
+++ b/core/viewer-wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/memento/ObjectAdapterMementoSupportUsingSpring.java
@@ -159,7 +159,7 @@ public class ObjectAdapterMementoSupportUsingSpring implements ObjectAdapterMeme
         switch (sort) {
         case MANAGED_BEAN:
 
-            val bean = serviceRegistry.lookupRegisteredBeanByNameElseFail(specId.asString());
+            val bean = serviceRegistry.lookupManagedBeanByNameElseFail(specId.asString());
             return ObjectAdapterForBean.of(bean, specificationLoader);
 
         case ENTITY:
diff --git a/examples/smoketests/src/test/resources/org/apache/isis/testdomain/bootstrapping/builtin-singleton.list b/examples/smoketests/src/test/resources/org/apache/isis/testdomain/bootstrapping/builtin-singleton.list
index 6c0e6a0..c524705 100644
--- a/examples/smoketests/src/test/resources/org/apache/isis/testdomain/bootstrapping/builtin-singleton.list
+++ b/examples/smoketests/src/test/resources/org/apache/isis/testdomain/bootstrapping/builtin-singleton.list
@@ -19,7 +19,7 @@ org.apache.isis.applib.services.urlencoding.UrlEncodingServiceWithCompression
 org.apache.isis.commons.internal.environment.IsisSystemEnvironment
 org.apache.isis.config.IsisConfiguration$PatternsConverter
 org.apache.isis.config.beans.IsisBeanFactoryPostProcessorForSpring
-org.apache.isis.config.beans.WebAppConfigBean
+#org.apache.isis.config.beans.WebAppConfigBean
 org.apache.isis.extensions.fixtures.FixturesEventService
 org.apache.isis.extensions.fixtures.FixturesLifecyleService
 org.apache.isis.extensions.fixtures.fixturescripts.ExecutionParametersService