Spring Bean
的创建过程非常的复杂,上一篇重点介绍了 Spring
在创建 Bean
的过程中,使用 InstantiationBeanPostProcessor
进行提前创建 Bean
,我们可以通过 CGLIB
创建对象对 Bean
的方法进行增强,当然也可以进行其他方式的创建方式。通过提前创建 Bean
,减少了调用 doCreateBean
方法的复杂逻辑的执行,而且通过这种方式可以定制创建的方式,便于扩展。
使用 supplier 进行Bean的提前暴露
接下来继续介绍 Spring
的创建过程,执行 doCreateBean
方法:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 实例化对象 instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // 省略代码.... }
这里会先从缓存中获取 FactoryBean
实例化的对象,如果有就进行下面的逻辑,一般来说基本是获取不到的,就会走下面创建 createBeanInstance
方法。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. // 解析Bean Class 用于创建对象 Class<?> beanClass = resolveBeanClass(mbd, beanName); // 判断class必须是public修饰的,否则报错 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } // 获取到supplier,如果不为空,则创建对象直接返回 // 扩展点,可以在这里进行对象的初始化创建,使用BFPP对BeanDefinition进行设置supplier Supplier<?