@ Nonnull public static final < T extends AbstractSingleton > T getSingleton ( @ Nonnull final IScope aScope , @ Nonnull final Class < T > aClass ) { ValueEnforcer . notNull ( aScope , "aScope" ) ; ValueEnforcer . notNull ( aClass , "Class" ) ; final String sSingletonScopeKey = getSingletonScopeKey ( aClass ) ; // check if already contained in passed scope T aInstance = s_aRWLock . readLocked ( ( ) -> aScope . attrs ( ) . getCastedValue ( sSingletonScopeKey ) ) ; if ( aInstance == null || aInstance . isInInstantiation ( ) ) { // Not yet present or just in instantiation // Safe instantiation check in write lock s_aRWLock . writeLock ( ) . lock ( ) ; try { // Check again in write lock aInstance = aScope . attrs ( ) . getCastedValue ( sSingletonScopeKey ) ; if ( aInstance == null ) { // Main instantiation aInstance = _instantiateSingleton ( aClass , aScope ) ; // Set in scope so that recursive calls to the same singleton are // caught appropriately aScope . attrs ( ) . putIn ( sSingletonScopeKey , aInstance ) ; // Start the initialization process // Do this after the instance was added to the scope aInstance . setInInstantiation ( true ) ; try { // Invoke callback method aInstance . onAfterInstantiation ( aScope ) ; // Set "instantiated" only if no exception was thrown aInstance . setInstantiated ( true ) ; } finally { // Ensure field is reset even in case of an exception aInstance . setInInstantiation ( false ) ; } // And some statistics s_aStatsCounterInstantiate . increment ( sSingletonScopeKey ) ; } else { // May not be instantiated if this method is called from the same // thread as the original instantiation } // We have the instance - maybe from re-querying the scope, maybe from // instantiation } finally { s_aRWLock . writeLock ( ) . unlock ( ) ; } } // This happens too often in practice, therefore this is disabled if ( SingletonHelper . isDebugConsistency ( ) ) { // Just a small note in case we're returning an unusable object if ( ! aInstance . isUsableObject ( ) ) if ( LOGGER . isWarnEnabled ( ) ) LOGGER . warn ( "Singleton '" + aClass . getName ( ) + "' is not usable - please check your calling order: " + aInstance . toString ( ) , SingletonHelper . getDebugStackTrace ( ) ) ; } return aInstance ; }
Get the singleton object in the passed scope using the passed class . If the singleton is not yet instantiated a new instance is created .