[Spring] BeanFactory.getBean流程

142 阅读3分钟

getBean流程

AbstractBeanFactory

AbstractBeanFactory的管理工作,scope:singleton|prototype|request|sessionAbstractBeanFactory中管理的.  AbstractBeanFactory是通过SingletonBeanRegistry完成对singleton bean的管理.

AbstractBeanFactory类图:

AbstractBeanFacotry extends FactoryBeanRegistrySupport:可以看到AbstractBeanFactory继承DefaultSignletonBeanRegistry, DefaultSignletonBeanRegistry实现了singleton的管理操作.

FactoryBeanRegistrySupportDefaultSignletonBeanRegistry的基础上增加对FactoryBean<?> Singleton 的管理.(ps: 对FactoryBean<?>和普通signleton bean的区别请自行了解)

DefaultSingletonBeanRegistry主要是使用 singletonObjects, signletonFactoriesearlySignletonObjects实现对singleton bean的管理.
singletonObjects: ConcurrentHashMap<String,Object>(256)
signletonFacotries: HashMap<String,ObjectFactory<?>>(16)
earlySingletonObjects: HashMap<String,Object>(16)

AbstractBeanFactory对于scope='prototype'的bean没有采用特殊的管理策略,每次getBean请求都会创建一个bean instance.

关于socpe='request|session',AbstractBeanFactory使用Scope进行管理. Scope实现类:

AbstractBeanFactory持有scopes:LinkedHashMap<String,Scope>(8)变量,可以管理不同的Scope: RequestScope以及SessionScope. 当然也可以管理自己定义的Scope.

Spring AbstractBeanFactory中管理bean的代码(节选):

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

   final String beanName = transformedBeanName(name);
   Object bean;
   // Eagerly check singleton cache for manually registered singletons.
   Object sharedInstance = getSingleton(beanName);
   if (sharedInstance != null && args == null) {
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   }
   else {
      try {
         // Create bean instance.
         if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  return createBean(beanName, mbd, args);
               }
            }
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }
         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            Object prototypeInstance = null;
            try {
               beforePrototypeCreation(beanName);
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }
         else {
            String scopeName = mbd.getScope();
            final Scope scope = this.scopes.get(scopeName);
               Object scopedInstance = scope.get(beanName, () -> {
                  beforePrototypeCreation(beanName);
                  try {
                     return createBean(beanName, mbd, args);
                  }
                  finally {
                     afterPrototypeCreation(beanName);
                  }
               });
            }
      }
      return (T) bean;
}

AbstractAutowireCapableBeanFactory

AbstractBeanFacotry中定义好bean的管理逻辑后, 创建bean的工作就交给子类AbstractAutowireCapableBeanFactory来实现: createBean()步骤

  1. resovleBeanClass: AbstractAutowireCapableBeanFactory在创建bean instance之前,先保证bean对应的Class<?>对象已经加载到JVM中来: resolveBeanClass(mbd,beanName) .

  2. createBeanInstance:在resolveBeanClass完成对bean Class的加载工作后,就可以开始createBeanInstance(). 在createBeanInstance中有4种方式创建bean instance.

    1. Supplier<?>: 暂时还不知道在spring中怎么使用的
    2. autowireConstructor: 使用带参构造函数实例化
    3. instantiateBean: 默认构造函数实例化bean
    4. instantiateUsingFacotryMethod: factory-method实例化bean

不论是使用构造函数实例化还是使用factory-method实例化,最终实例化使用反射Reflect来实现的.
ctor.newInstance()|ctor.newInstance(args): 构造方法实例化
factoryMthod.invoke(factoryBean,args): factory-method实例化

  1. populateBean: 在populateBean中完成了Spring beanFactoryautowire功能.

Spring配置文件方式的autowire通过autowireByName()autowireByType()完成.
对于@Autowire|@Inject|@Value|@Lookup等注解方式的自动注入则是通过hook: InstantiationAwareBeanPostProcessor. postProcessPropertyValues()来实现的.

AutowiredAnnotationBeanPostProcessor   
RequiredAnnotationBeanPostProcessor

populateBean中,还预留了一个hook: InstantiationAwareBeanPostProcessor. postProcessAfterInstantiation(), 可以通过这个hook实现自定义字段注入: 在spring自己的autowire之前.
4. initializeBean: 在initializeBean中完成对bean instance的初始化工作.
这里的初始化工作指的是在spring contexnt中配置的init-mehod: <bean id=’xx’ class=’xxxx’ init-method=’init’>. 在initializeBean中会通过反射的方式调用初始化方法进行初始化: initMethod.invoke().
如果bean实现了InitializingBean接口,(InitializingBean)bean.afterPropertiesSet() 将被调用,完成初始化. InitializingBean.afterPropertiesSet()和自定义的初始化可以同时存在. 如果bean实现了BeanNameAware|BeanClassLoaderAware|BeanFactoryAware,也会设置对应的初始值.

(BeanNameAware)bean.setBeanName(beanName)
(BeanClassLoaderAware)bean.setBeanClassLoader(getBeanClassLoader())
(BeanFactoryAware)bean.setBeanFactory(AbstractAutowireCapableBeanFactor.class)

hook:BeanPostProcessor

BeanPostProcessorSpring BeanFactory的身份就是一个Hook. 辅助BeanFactory实现Spring要求的一些功能和对外提供接口拓展. 常见的使用场景:

  1. Spring @Autowired/@Value/@Inject/@Lookup等注解实现的字段注入; 也可实现自定义的字段注入
  2. 检查bean是否实现指定接口
  3. 使用proxy包装bean

BeanPostProcessor类图:

BeanPostProcessorSpring beanFactory中的出现顺序:

  1. resolveBeanClass
    Class.forName()/ classLoader.loadClass()加载bean Class.

  2. hook: InstantiationAwareBeanPostProcessor.postProcessorBeforeInstantiation 出现在resolveBeanClass将bean Class加载完成之后. Code如下:

  3. createBeanInstance

  4. hook: MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition

  5. populateBean

  6. hook: InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

  7. autowireByType()|autowireByName()

  8. hook: InstantiationAwareBeanPostProcessor.postProcessPropertyValues()

  9. applyPropertyValues

  10. initializeBean

  11. invokeAwareMethod

  12. hook: BeanPostProcessor.postProcessBeforeInitialization()

  13. invokeInitMethod

  14. hook: BeanPostProcessor.posrtProcessAfterInitialization()