Spring创建对象的主要方式有
通过自定义BeanPostProcessor,生成代理对象InstantiationAwareBeanPostProcessor
createBean() -> resolveBeforeInstantiation()
通过supplier创建对象
createBean() -> doCreateBean() -> createBeanInstance() -> obtainFromSupplier()
通过FactoryMethod创建对象
createBean() -> doCreateBean() -> createBeanInstance() -> instantiateUsingFactoryMethod()
通过反射创建对象
createBean() -> doCreateBean() -> createBeanInstance() -> instantiateBean()
通过FactoryBean创建对象
本文介绍下最后一种,如何通过supplier创建Bean(保姆级教程,建议收藏食用(。・ω・。)ノ)

public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public User(){}public User(String name) {this.name = name;}
}

public class CreateSupplier {public static User createUser() {return new User("aqin");}
}

public class SupplierBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanDefinition;genericBeanDefinition.setInstanceSupplier(CreateSupplier::createUser);genericBeanDefinition.setBeanClass(User.class);}
}


public class TestSupplier {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("supplier.xml");User user = applicationContext.getBean(User.class);System.out.println(user.getName());}
}

由于是测试创建Bean,我们需要在doCreateBean()上打个断点,启动debug,执行到断点位置,如下图:

进入doCreateBean(),下一步到instanceWrapper = createBeanInstance(beanName, mbd, args);,进入createBeanInstance()方法中

进入createBeanInstance()方法后,下一步到Supplier> instanceSupplier = mbd.getInstanceSupplier();这里是判断当前beanDefinition中是否包含实例供应器的

继续下一步,我们会发现instanceSupplier=null,咦?……不应该呀?

不用着急,我们仔细看上图中红框框圈住的内容,有一个是beanName,此时,beanName是"supplierBeanFactoryPostProcessor",并非我们要创建的"user"
所以我们直接点击下图中的Resume Program再次进入之前的断点即可

点击上图中的绿三角,就会再次停在一开始我们打断点的位置,如下图:

此时可以看到,当前处理对象的beanName为"user",继续下一步,直到再次执行到Supplier> instanceSupplier = mbd.getInstanceSupplier()

进入getInstanceSupplier(),可以发现instanceWrapper已经不是null叻

再向下执行一步,由于instanceSupplier已经有了值,所以会进入if的逻辑,通过obtainFromSupplier()方法返回已获取到的对象

obtainFromSupplier()从给定“供应商”处,获取Bean实例

然后包装一下,再进行初始化

完成(。・ω・。)ノ
上一篇:ZMQ之共享键值缓存(克隆模式)
下一篇:通关算法题之 ⌈二叉树⌋ 下