Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2017 - 2024 the original author or authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see [https://www.gnu.org/licenses/]
*/
package infra.beans.factory.support;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Supplier;
import infra.beans.factory.BeanCreationException;
import infra.beans.factory.BeanCreationNotAllowedException;
import infra.beans.factory.BeanCurrentlyInCreationException;
import infra.beans.factory.BeanFactory;
import infra.beans.factory.DisposableBean;
import infra.beans.factory.config.ConfigurableBeanFactory;
import infra.beans.factory.config.SingletonBeanRegistry;
import infra.core.DefaultAliasRegistry;
import infra.lang.Assert;
import infra.lang.Constant;
import infra.lang.NullValue;
import infra.lang.Nullable;
import infra.util.CollectionUtils;
import infra.util.StringUtils;
/**
* Generic registry for shared bean instances, implementing the
* {@link SingletonBeanRegistry}.
* Allows for registering singleton instances that should be shared
* for all callers of the registry, to be obtained via bean name.
*
*
Also supports registration of {@link DisposableBean} instances,
* (which might or might not correspond to registered singletons),
* to be destroyed on shutdown of the registry. Dependencies between
* beans can be registered to enforce an appropriate shutdown order.
*
*
This class mainly serves as base class for {@link BeanFactory}
* implementations, factoring out the common management of singleton
* bean instances. Note that the {@link ConfigurableBeanFactory}
* interface extends the {@link SingletonBeanRegistry} interface.
*
*
Note that this class assumes neither a bean definition concept
* nor a specific creation process for bean instances, in contrast to
* {@link AbstractBeanFactory} and {@link StandardBeanFactory}
* (which inherit from it). Can alternatively also be used as a nested
* helper to delegate to.
*
* @author Juergen Hoeller
* @author Harry Yang
* @see #registerSingleton
* @see #registerDisposableBean
* @see DisposableBean
* @see ConfigurableBeanFactory
* @since 4.0 2021/10/1 22:47
*/
public class DefaultSingletonBeanRegistry extends DefaultAliasRegistry implements SingletonBeanRegistry {
/** Maximum number of suppressed exceptions to preserve. */
private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;
/** Collection of suppressed Exceptions, available for associating related causes. */
@Nullable
private Set suppressedExceptions;
/** Flag that indicates whether we're currently within destroySingletons. */
private boolean singletonsCurrentlyInDestruction = false;
private final ReentrantLock singletonLock = new ReentrantLock();
/** Names of beans that are currently in creation. */
private final Set singletonsCurrentlyInCreation = ConcurrentHashMap.newKeySet(16);
/** Names of beans currently excluded from in creation checks. */
private final Set inCreationCheckExclusions = ConcurrentHashMap.newKeySet(16);
/** Set of registered singletons, containing the bean names in registration order. */
private final Set registeredSingletons = Collections.synchronizedSet(new LinkedHashSet<>(256));
/** Disposable bean instances: bean name to disposable instance. */
private final LinkedHashMap disposableBeans = new LinkedHashMap<>();
/** Map between containing bean names: bean name to Set of bean names that the bean contains. */
private final ConcurrentHashMap> containedBeanMap = new ConcurrentHashMap<>(16);
/** Map between dependent bean names: bean name to Set of dependent bean names. */
private final ConcurrentHashMap> dependentBeanMap = new ConcurrentHashMap<>(64);
/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
private final ConcurrentHashMap> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
/** Cache of singleton objects: bean name to bean instance. */
private final ConcurrentHashMap singletonObjects = new ConcurrentHashMap<>(128);
/** Cache of early singleton objects: bean name to bean instance. */
private final ConcurrentHashMap earlySingletonObjects = new ConcurrentHashMap<>(16);
/** Cache of singleton factories: bean name to ObjectFactory. */
private final ConcurrentHashMap> singletonFactories = new ConcurrentHashMap<>(16);
/** Custom callbacks for singleton creation/registration. */
private final ConcurrentHashMap> singletonCallbacks = new ConcurrentHashMap<>(16);
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name is required");
Assert.notNull(singletonObject, "Singleton object is required");
this.singletonLock.lock();
try {
addSingleton(beanName, singletonObject);
}
finally {
this.singletonLock.unlock();
}
}
/**
* Add the given singleton object to the singleton cache of this factory.
*
To be called for eager registration of singletons.
*
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, Object singletonObject) {
Object oldObject = this.singletonObjects.putIfAbsent(beanName, singletonObject);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [%s] under bean name '%s': there is already object [%s] bound"
.formatted(singletonObject, beanName, oldObject));
}
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
Consumer