FactoryBean的使用

一般的bean是通过<bean/>标签中的class属性通过反射将类进行实例化,FactoryBean的话,先是获取FactoryBean的bean对象,然后调用其getObject方法,返回bean,
若就是想要FactoryBean的话需要&加载beanName前面

缓存中获取单例bean

Spring保证同一个bean在容器中只有一个,先从一级缓存中获取,之后再次尝试从singletonFactories。Spring不等bean创建完成就会将创建的bean提早爆光到singletonFactories

  1. @Override
  2. @Nullable
  3. public Object getSingleton(String beanName) {
  4. return getSingleton(beanName, true);
  5. }
  6. /**
  7. * Return the (raw) singleton object registered under the given name.
  8. * <p>Checks already instantiated singletons and also allows for an early
  9. * reference to a currently created singleton (resolving a circular reference).
  10. * @param beanName the name of the bean to look for
  11. * @param allowEarlyReference whether early references should be created or not
  12. * @return the registered singleton object, or {@code null} if none found
  13. */
  14. @Nullable
  15. protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  16. // Quick check for existing instance without full singleton lock
  17. Object singletonObject = this.singletonObjects.get(beanName);
  18. if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
  19. singletonObject = this.earlySingletonObjects.get(beanName);
  20. if (singletonObject == null && allowEarlyReference) {
  21. synchronized (this.singletonObjects) {
  22. // Consistent creation of early reference within full singleton lock
  23. singletonObject = this.singletonObjects.get(beanName);
  24. if (singletonObject == null) {
  25. singletonObject = this.earlySingletonObjects.get(beanName);
  26. if (singletonObject == null) {
  27. ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
  28. if (singletonFactory != null) {
  29. singletonObject = singletonFactory.getObject();
  30. this.earlySingletonObjects.put(beanName, singletonObject);
  31. this.singletonFactories.remove(beanName);
  32. }
  33. }
  34. }
  35. }
  36. }
  37. }
  38. return singletonObject;
  39. }
  1. 先从singletonObjects中尝试获取实例
  2. 获取不到,尝试从earlySingletonObjects中获取
  3. 再获取不到,尝试从singletonFactories中获取ObjectFactory,调用lamda的getObject方法
  4. 生成成功后,放入earlySingletonObjects, singletonFactories移除beanName对应的ObjectFactory
    1. singletonObjects:一级缓存,beanName —> bean instance
    2. earlySingletonObjects:二级缓存,bean —> 正在创建的bean实例
    3. singletonFactories:三级缓存,beanName —> ObjectFactory
    4. registeredSingletons:用来保存已经注册的bean

从bean中获取对象

从缓存中获取beanInstance后,会调用getObjectForBeanInstance,这个方法实际就是检测是否为FactoryBean实例,若是FactoryBean实例的话,会调用getObject作为返回值

  1. protected Object getObjectForBeanInstance(
  2. Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
  3. // Don't let calling code try to dereference the factory if the bean isn't a factory.
  4. if (BeanFactoryUtils.isFactoryDereference(name)) {
  5. if (beanInstance instanceof NullBean) {
  6. return beanInstance;
  7. }
  8. if (!(beanInstance instanceof FactoryBean)) {
  9. throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
  10. }
  11. if (mbd != null) {
  12. mbd.isFactoryBean = true;
  13. }
  14. return beanInstance;
  15. }
  16. // Now we have the bean instance, which may be a normal bean or a FactoryBean.
  17. // If it's a FactoryBean, we use it to create a bean instance, unless the
  18. // caller actually wants a reference to the factory.
  19. if (!(beanInstance instanceof FactoryBean)) {
  20. return beanInstance;
  21. }
  22. Object object = null;
  23. if (mbd != null) {
  24. mbd.isFactoryBean = true;
  25. }
  26. else {
  27. //尝试从 缓存中 获取 该 FactoryBean 生成的bean
  28. object = getCachedObjectForFactoryBean(beanName);
  29. }
  30. if (object == null) {
  31. // Return bean instance from factory.
  32. FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
  33. // Caches object obtained from FactoryBean if it is a singleton.
  34. if (mbd == null && containsBeanDefinition(beanName)) {
  35. //若xml中也定义了,会尝试合并父类属性
  36. mbd = getMergedLocalBeanDefinition(beanName);
  37. }
  38. boolean synthetic = (mbd != null && mbd.isSynthetic());
  39. object = getObjectFromFactoryBean(factory, beanName, !synthetic);
  40. }
  41. return object;
  42. }
  1. 对FactoryBean引用正确性的验证,验证通过直接不做任何处理返回
  2. 对非FactoryBean不做任何处理
  3. 对bean转换成FactoryBean
  4. 获取bean的父类配置并合并
  5. 执行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)) {
      1. synchronized (getSingletonMutex()) {
      2. Object object = this.factoryBeanObjectCache.get(beanName);
      3. if (object == null) {
      4. object = doGetObjectFromFactoryBean(factory, beanName);
      5. // Only post-process and store if not put there already during getObject() call above
      6. // (e.g. because of circular reference processing triggered by custom getBean calls)
      7. Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
      8. if (alreadyThere != null) {
      9. object = alreadyThere;
      10. }
      11. else {
      12. if (shouldPostProcess) {
      13. if (isSingletonCurrentlyInCreation(beanName)) {
      14. // Temporarily return non-post-processed object, not storing it yet..
      15. return object;
      16. }
      17. beforeSingletonCreation(beanName);
      18. try {
      19. object = postProcessObjectFromFactoryBean(object, beanName);
      20. }
      21. catch (Throwable ex) {
      22. throw new BeanCreationException(beanName,
      23. "Post-processing of FactoryBean's singleton object failed", ex);
      24. }
      25. finally {
      26. afterSingletonCreation(beanName);
      27. }
      28. }
      29. if (containsSingleton(beanName)) {
      30. this.factoryBeanObjectCache.put(beanName, object);
      31. }
      32. }
      33. }
      34. return object;
      35. }
      } else {
      1. Object object = doGetObjectFromFactoryBean(factory, beanName);
      2. if (shouldPostProcess) {
      3. try {
      4. object = postProcessObjectFromFactoryBean(object, beanName);
      5. }
      6. catch (Throwable ex) {
      7. throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
      8. }
      9. }
      10. return object;
      } }
  1. 6. FactoryBean是单例模式的,会尝试缓存中获取,获取不到再走`doGetObjectFromFactoryBean`
  2. 7. FactoryBean不是单例模式,直接走`doGetObjectFromFactoryBean``getObject`
  3. ```java
  4. private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
  5. Object object;
  6. try {
  7. if (System.getSecurityManager() != null) {
  8. AccessControlContext acc = getAccessControlContext();
  9. try {
  10. object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
  11. }
  12. catch (PrivilegedActionException pae) {
  13. throw pae.getException();
  14. }
  15. }
  16. else {
  17. object = factory.getObject();
  18. }
  19. }
  20. catch (FactoryBeanNotInitializedException ex) {
  21. throw new BeanCurrentlyInCreationException(beanName, ex.toString());
  22. }
  23. catch (Throwable ex) {
  24. throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
  25. }
  26. // Do not accept a null value for a FactoryBean that's not fully
  27. // initialized yet: Many FactoryBeans just return null then.
  28. if (object == null) {
  29. if (isSingletonCurrentlyInCreation(beanName)) {
  30. throw new BeanCurrentlyInCreationException(
  31. beanName, "FactoryBean which is currently in creation returned null from getObject");
  32. }
  33. object = new NullBean();
  34. }
  35. return object;
  36. }
  1. doGetObjectFromFactoryBean方法结束后,会调用BeanPostProcessor
    1. @Override
    2. protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
    3. return applyBeanPostProcessorsAfterInitialization(object, beanName);
    4. }

以上是可以从缓存中获取到bean的一个逻辑流程, 对于普通bean和FactoryBean引用,获取后就结束了 对于FactoryBean,会走一个较为复杂的流程,去调用getObject方法,并执行后置处理器的逻辑

获取单例

在三级缓存中获取不到Bean之后,会去父级容器去寻找一番,没有的话就自己来,自己来之前,会先解决depend-on的问题,最后根据是否为单例模式,来调用这行代码

  1. if (mbd.isSingleton()) {
  2. sharedInstance = getSingleton(beanName, () -> {
  3. try {
  4. return createBean(beanName, mbd, args);
  5. }
  6. catch (BeansException ex) {
  7. // Explicitly remove instance from singleton cache: It might have been put there
  8. // eagerly by the creation process, to allow for circular reference resolution.
  9. // Also remove any beans that received a temporary reference to the bean.
  10. destroySingleton(beanName);
  11. throw ex;
  12. }
  13. });
  14. beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  15. }

来看看getSingleton里执行了啥逻辑

  1. public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  2. Assert.notNull(beanName, "Bean name must not be null");
  3. synchronized (this.singletonObjects) {
  4. Object singletonObject = this.singletonObjects.get(beanName);
  5. if (singletonObject == null) {
  6. if (this.singletonsCurrentlyInDestruction) {
  7. throw new BeanCreationNotAllowedException(beanName,
  8. "Singleton bean creation not allowed while singletons of this factory are in destruction " +
  9. "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
  10. }
  11. if (logger.isDebugEnabled()) {
  12. logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
  13. }
  14. beforeSingletonCreation(beanName);
  15. boolean newSingleton = false;
  16. boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
  17. if (recordSuppressedExceptions) {
  18. this.suppressedExceptions = new LinkedHashSet<>();
  19. }
  20. try {
  21. singletonObject = singletonFactory.getObject();
  22. newSingleton = true;
  23. }
  24. catch (IllegalStateException ex) {
  25. // Has the singleton object implicitly appeared in the meantime ->
  26. // if yes, proceed with it since the exception indicates that state.
  27. singletonObject = this.singletonObjects.get(beanName);
  28. if (singletonObject == null) {
  29. throw ex;
  30. }
  31. }
  32. catch (BeanCreationException ex) {
  33. if (recordSuppressedExceptions) {
  34. for (Exception suppressedException : this.suppressedExceptions) {
  35. ex.addRelatedCause(suppressedException);
  36. }
  37. }
  38. throw ex;
  39. }
  40. finally {
  41. if (recordSuppressedExceptions) {
  42. this.suppressedExceptions = null;
  43. }
  44. afterSingletonCreation(beanName);
  45. }
  46. if (newSingleton) {
  47. addSingleton(beanName, singletonObject);
  48. }
  49. }
  50. return singletonObject;
  51. }
  52. }
  1. 加锁后,再次确认bean单例没有被缓存过
  2. 通过beforeSingletonCreation中记录此beanName正处在创建中,加入singletonsCurrentlyInDestruction,这样就这样便可以对循环依赖进行检测
  3. 调用lamda表达式的getObject方法,最终是createBean方法,后面我们再看
  4. 执行afterSingletonCreation方法,会执行2步骤相反的操作
  5. 调用addSingleton方法,加入一级缓存,标记已经注册成功,并将二三级缓存清除

真正创建Bean-createBean方法

在获取单例的步骤里,会调用lamda表达式的getObject方法

  1. sharedInstance = getSingleton(beanName, () -> {
  2. try {
  3. return createBean(beanName, mbd, args);
  4. }
  5. catch (BeansException ex) {
  6. // Explicitly remove instance from singleton cache: It might have been put there
  7. // eagerly by the creation process, to allow for circular reference resolution.
  8. // Also remove any beans that received a temporary reference to the bean.
  9. destroySingleton(beanName);
  10. throw ex;
  11. }
  12. });

看看这个lamda表达,最后走的是return createBean(beanName, mbd, args);

  1. @Override
  2. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  3. throws BeanCreationException {
  4. if (logger.isTraceEnabled()) {
  5. logger.trace("Creating instance of bean '" + beanName + "'");
  6. }
  7. RootBeanDefinition mbdToUse = mbd;
  8. // Make sure bean class is actually resolved at this point, and
  9. // clone the bean definition in case of a dynamically resolved Class
  10. // which cannot be stored in the shared merged bean definition.
  11. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  12. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  13. mbdToUse = new RootBeanDefinition(mbd);
  14. mbdToUse.setBeanClass(resolvedClass);
  15. }
  16. // Prepare method overrides.
  17. try {
  18. mbdToUse.prepareMethodOverrides();
  19. }
  20. catch (BeanDefinitionValidationException ex) {
  21. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
  22. beanName, "Validation of method overrides failed", ex);
  23. }
  24. try {
  25. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  26. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  27. if (bean != null) {
  28. return bean;
  29. }
  30. }
  31. catch (Throwable ex) {
  32. throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
  33. "BeanPostProcessor before instantiation of bean failed", ex);
  34. }
  35. try {
  36. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  37. if (logger.isTraceEnabled()) {
  38. logger.trace("Finished creating instance of bean '" + beanName + "'");
  39. }
  40. return beanInstance;
  41. }
  42. catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  43. // A previously detected exception with proper bean creation context already,
  44. // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
  45. throw ex;
  46. }
  47. catch (Throwable ex) {
  48. throw new BeanCreationException(
  49. mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  50. }
  51. }
  1. 解析出来className
  2. override属性进行标记及验证,主要针对lookup-method和replace-method的
  3. 应用BeanPostProcessor(InstantiationAwareBeanPostProcessor)这种类型的,注释解释是返回一个代理对象的机会
  4. 执行doCreateBean方法

    处理override属性

    暂时只知道下面几个点:

  5. 会读取BeanDefinition中的methodOverrides,这里记录的是lookup-methodreplace-method

  6. bean实例化时,若methodOverrides有值,会为bean生成代理

    实例化前置处理

    这一步骤如果处理后返回了bean,则后续的doCreateBean方法就直接不需要再去做了。
    我们的AOP功能就是在这一步做的判断

    1. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    2. Object bean = null;
    3. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    4. // Make sure bean class is actually resolved at this point.
    5. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    6. Class<?> targetType = determineTargetType(beanName, mbd);
    7. if (targetType != null) {
    8. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    9. if (bean != null) {
    10. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    11. }
    12. }
    13. }
    14. mbd.beforeInstantiationResolved = (bean != null);
    15. }
    16. return bean;
    17. }
  7. 实例化前的后置处理

    1. @Nullable
    2. protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    3. for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    4. Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
    5. if (result != null) {
    6. return result;
    7. }
    8. }
    9. return null;
    10. }

    在调用前置方法时,就可能生成一个代理对象了。

  8. 实例化后的处理逻辑

    1. @Override
    2. public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    3. throws BeansException {
    4. Object result = existingBean;
    5. for (BeanPostProcessor processor : getBeanPostProcessors()) {
    6. Object current = processor.postProcessAfterInitialization(result, beanName);
    7. if (current == null) {
    8. return result;
    9. }
    10. result = current;
    11. }
    12. return result;
    13. }

    若真得返回了一个代理bean,则直接引用所有的后置处理