FactoryBean的使用
一般的bean是通过<bean/>标签中的class属性通过反射将类进行实例化,FactoryBean的话,先是获取FactoryBean的bean对象,然后调用其getObject方法,返回bean,
若就是想要FactoryBean的话需要&加载beanName前面
缓存中获取单例bean
Spring保证同一个bean在容器中只有一个,先从一级缓存中获取,之后再次尝试从singletonFactories。Spring不等bean创建完成就会将创建的bean提早爆光到singletonFactories。
@Override@Nullablepublic Object getSingleton(String beanName) {return getSingleton(beanName, true);}/*** Return the (raw) singleton object registered under the given name.* <p>Checks already instantiated singletons and also allows for an early* reference to a currently created singleton (resolving a circular reference).* @param beanName the name of the bean to look for* @param allowEarlyReference whether early references should be created or not* @return the registered singleton object, or {@code null} if none found*/@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// Quick check for existing instance without full singleton lockObject singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {synchronized (this.singletonObjects) {// Consistent creation of early reference within full singleton locksingletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}}}return singletonObject;}
- 先从
singletonObjects中尝试获取实例 - 获取不到,尝试从
earlySingletonObjects中获取 - 再获取不到,尝试从
singletonFactories中获取ObjectFactory,调用lamda的getObject方法 - 生成成功后,放入
earlySingletonObjects,singletonFactories移除beanName对应的ObjectFactory- singletonObjects:一级缓存,beanName —> bean instance
 - earlySingletonObjects:二级缓存,bean —> 正在创建的bean实例
 - singletonFactories:三级缓存,beanName —> ObjectFactory
 - registeredSingletons:用来保存已经注册的bean
 
 
从bean中获取对象
从缓存中获取beanInstance后,会调用getObjectForBeanInstance,这个方法实际就是检测是否为FactoryBean实例,若是FactoryBean实例的话,会调用getObject作为返回值
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {// Don't let calling code try to dereference the factory if the bean isn't a factory.if (BeanFactoryUtils.isFactoryDereference(name)) {if (beanInstance instanceof NullBean) {return beanInstance;}if (!(beanInstance instanceof FactoryBean)) {throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());}if (mbd != null) {mbd.isFactoryBean = true;}return beanInstance;}// Now we have the bean instance, which may be a normal bean or a FactoryBean.// If it's a FactoryBean, we use it to create a bean instance, unless the// caller actually wants a reference to the factory.if (!(beanInstance instanceof FactoryBean)) {return beanInstance;}Object object = null;if (mbd != null) {mbd.isFactoryBean = true;}else {//尝试从 缓存中 获取 该 FactoryBean 生成的beanobject = getCachedObjectForFactoryBean(beanName);}if (object == null) {// Return bean instance from factory.FactoryBean<?> factory = (FactoryBean<?>) beanInstance;// Caches object obtained from FactoryBean if it is a singleton.if (mbd == null && containsBeanDefinition(beanName)) {//若xml中也定义了,会尝试合并父类属性mbd = getMergedLocalBeanDefinition(beanName);}boolean synthetic = (mbd != null && mbd.isSynthetic());object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}
- 对FactoryBean引用正确性的验证,验证通过直接不做任何处理返回
 - 对非FactoryBean不做任何处理
 - 对bean转换成FactoryBean
 - 获取bean的父类配置并合并
 - 执行
getObjectFromFactoryBean方法 ```java /**- Obtain an object to expose from the given FactoryBean.
 - @param factory the FactoryBean instance
 - @param beanName the name of the bean
 - @param shouldPostProcess whether the bean is subject to post-processing
 - @return the object obtained from the FactoryBean
 - @throws BeanCreationException if FactoryBean object creation failed
 - @see org.springframework.beans.factory.FactoryBean#getObject()
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
 //
 if (factory.isSingleton() && containsSingleton(beanName)) {
} else {synchronized (getSingletonMutex()) {Object object = this.factoryBeanObjectCache.get(beanName);if (object == null) {object = doGetObjectFromFactoryBean(factory, beanName);// Only post-process and store if not put there already during getObject() call above// (e.g. because of circular reference processing triggered by custom getBean calls)Object alreadyThere = this.factoryBeanObjectCache.get(beanName);if (alreadyThere != null) {object = alreadyThere;}else {if (shouldPostProcess) {if (isSingletonCurrentlyInCreation(beanName)) {// Temporarily return non-post-processed object, not storing it yet..return object;}beforeSingletonCreation(beanName);try {object = postProcessObjectFromFactoryBean(object, beanName);}catch (Throwable ex) {throw new BeanCreationException(beanName,"Post-processing of FactoryBean's singleton object failed", ex);}finally {afterSingletonCreation(beanName);}}if (containsSingleton(beanName)) {this.factoryBeanObjectCache.put(beanName, object);}}}return object;}
} }Object object = doGetObjectFromFactoryBean(factory, beanName);if (shouldPostProcess) {try {object = postProcessObjectFromFactoryBean(object, beanName);}catch (Throwable ex) {throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);}}return object;
 
 
6. 若FactoryBean是单例模式的,会尝试缓存中获取,获取不到再走`doGetObjectFromFactoryBean`7. 若FactoryBean不是单例模式,直接走`doGetObjectFromFactoryBean`去`getObject````javaprivate Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {Object object;try {if (System.getSecurityManager() != null) {AccessControlContext acc = getAccessControlContext();try {object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);}catch (PrivilegedActionException pae) {throw pae.getException();}}else {object = factory.getObject();}}catch (FactoryBeanNotInitializedException ex) {throw new BeanCurrentlyInCreationException(beanName, ex.toString());}catch (Throwable ex) {throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);}// Do not accept a null value for a FactoryBean that's not fully// initialized yet: Many FactoryBeans just return null then.if (object == null) {if (isSingletonCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");}object = new NullBean();}return object;}
doGetObjectFromFactoryBean方法结束后,会调用BeanPostProcessor@Overrideprotected Object postProcessObjectFromFactoryBean(Object object, String beanName) {return applyBeanPostProcessorsAfterInitialization(object, beanName);}
以上是可以从缓存中获取到bean的一个逻辑流程, 对于普通bean和FactoryBean引用,获取后就结束了 对于FactoryBean,会走一个较为复杂的流程,去调用getObject方法,并执行后置处理器的逻辑
获取单例
在三级缓存中获取不到Bean之后,会去父级容器去寻找一番,没有的话就自己来,自己来之前,会先解决depend-on的问题,最后根据是否为单例模式,来调用这行代码
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;}});beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}
来看看getSingleton里执行了啥逻辑
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,"Singleton bean creation not allowed while singletons of this factory are in destruction " +"(Do not request a bean from a BeanFactory in a destroy method implementation!)");}if (logger.isDebugEnabled()) {logger.debug("Creating shared instance of singleton bean '" + beanName + "'");}beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {singletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {// Has the singleton object implicitly appeared in the meantime ->// if yes, proceed with it since the exception indicates that state.singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {throw ex;}}catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {ex.addRelatedCause(suppressedException);}}throw ex;}finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}afterSingletonCreation(beanName);}if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}}
- 加锁后,再次确认bean单例没有被缓存过
 - 通过beforeSingletonCreation中记录此beanName正处在创建中,加入
singletonsCurrentlyInDestruction,这样就这样便可以对循环依赖进行检测 - 调用lamda表达式的getObject方法,最终是createBean方法,后面我们再看
 - 执行
afterSingletonCreation方法,会执行2步骤相反的操作 - 调用
addSingleton方法,加入一级缓存,标记已经注册成功,并将二三级缓存清除 
真正创建Bean-createBean方法
在获取单例的步骤里,会调用lamda表达式的getObject方法
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;}});
看看这个lamda表达,最后走的是return createBean(beanName, mbd, args);
@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}try {Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}}
- 解析出来className
 - 对
override属性进行标记及验证,主要针对lookup-method和replace-method的 - 应用BeanPostProcessor(InstantiationAwareBeanPostProcessor)这种类型的,注释解释是返回一个代理对象的机会
 - 
处理override属性
暂时只知道下面几个点:
 会读取BeanDefinition中的methodOverrides,这里记录的是
lookup-method和replace-methodbean实例化时,若methodOverrides有值,会为bean生成代理
实例化前置处理
这一步骤如果处理后返回了bean,则后续的
doCreateBean方法就直接不需要再去做了。
我们的AOP功能就是在这一步做的判断protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}
实例化前的后置处理
@Nullableprotected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}return null;}
在调用前置方法时,就可能生成一个代理对象了。
实例化后的处理逻辑
@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}
若真得返回了一个代理bean,则直接引用所有的后置处理
