* If a bean implements this * interface, itisusedasafactoryforanobjecttoexpose, notdirectlyasa * beaninstancethatwillbeexposeditself. * * <p><b>NB: Abeanthatimplementsthisinterfacecannotbeusedasanormalbean.</b> * AFactoryBeanisdefinedinabeanstyle, buttheobjectexposedforbean * references ({@link #getObject()}) is always the object that it creates.
/** * Expose the singleton instance or create a new prototype instance. * @see #createInstance() * @see #getEarlySingletonInterfaces() */ @Override publicfinal T getObject()throws Exception { if (isSingleton()) { return (this.initialized ? this.singletonInstance : getEarlySingletonInstance()); } else { return createInstance(); } }
/** * Template method that subclasses must override to construct * the object returned by this factory. * <p>Invoked on initialization of this FactoryBean in case of * a singleton; else, on each {@link #getObject()} call. * @return the object returned by this factory * @throws Exception if an exception occurred during object creation * @see #getObject() */ protectedabstract T createInstance()throws Exception;
// SimpleAliasRegistry.java /** * Transitively retrieve all aliases for the given name. * @param name the target name to find aliases for * @param result the resulting aliases list */ privatevoidretrieveAliases(String name, List<String> result){ this.aliasMap.forEach((alias, registeredName) -> { if (registeredName.equals(name)) { result.add(alias); retrieveAliases(alias, result); } }); }
/** Cache of singleton objects: bean name to bean instance. */ privatefinal Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */ privatefinal Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */ privatefinal Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** Set of registered singletons, containing the bean names in registration order. */ privatefinal Set<String> registeredSingletons = new LinkedHashSet<>(256);
/** Names of beans that are currently in creation. */ privatefinal Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/** Names of beans currently excluded from in creation checks. */ privatefinal Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/** List of suppressed Exceptions, available for associating related causes. */ @Nullable private Set<Exception> suppressedExceptions;
/** Flag that indicates whether we're currently within destroySingletons. */ privateboolean singletonsCurrentlyInDestruction = false;
/** Disposable bean instances: bean name to disposable instance. */ privatefinal Map<String, Object> disposableBeans = new LinkedHashMap<>();
/** Map between containing bean names: bean name to Set of bean names that the bean contains. */ privatefinal Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
/** Map between dependent bean names: bean name to Set of dependent bean names. */ privatefinal Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */ privatefinal Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
/** * Obtain an object to expose from the given FactoryBean. * @param factory the FactoryBean instance * @param beanName the name of the bean * @return the object obtained from the FactoryBean * @throws BeanCreationException if FactoryBean object creation failed * @see org.springframework.beans.factory.FactoryBean#getObject() */ private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException {
/** * Return an instance, which may be shared or independent, of the specified bean. */ protected <T> T doGetBean(final String name, @Nullablefinal Class<T> requiredType, @Nullablefinal Object[] args, boolean typeCheckOnly)throws BeansException { ...
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { thrownew BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { thrownew BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } ... }
/** * Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. * <p>Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. */ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd){ if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); returnnull; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); }
在代码中我们可以清晰的看到一个bean被初始化的生命周期:实例化->组装各种依赖->调用Aware接口方法->调用BeanPostProcessor的before方法->指定的”init-method”方法->调用BeanPostProcessor的after方法。关于生命周期,《Spring In Action》这本书中有详细讲解。