【Spring源码系列- IOC】
本文目录
SupplierBeanFactoryPostProcessor.java
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 {
- @Override
- public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
- BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");
- GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanDefinition;
- genericBeanDefinition.setInstanceSupplier(CreateSupplier::createUser);
- genericBeanDefinition.setBeanClass(User.class);
- }
- }

- "1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
-
- <bean id="user" class="com.aqin.custom.supplier.User">bean>
- <bean id="supplierBeanFactoryPostProcessor" class="com.aqin.custom.supplier.SupplierBeanFactoryPostProcessor">bean>
- beans>

- 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实例

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

完成(。・ω・。)ノ