通过用户指定的 Supplier 来创建对象。我们可以在扩展点中给 bean 定义增加自定义的 Supplier。

    1. // 通过给定的函数获取对象
    2. Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    3. if (instanceSupplier != null) {
    4. return obtainFromSupplier(instanceSupplier, beanName);
    5. }

    代码测试

    1. public class SuA {
    2. private String name;
    3. public SuA() {
    4. }
    5. public SuA(String name) {
    6. this.name = name;
    7. }
    8. public String getName() {
    9. return name;
    10. }
    11. public void setName(String name) {
    12. this.name = name;
    13. }
    14. }

    自定义Supplier

    1. public class OrgSupplier {
    2. public static SuA create() {
    3. return new SuA("Hello");
    4. }
    5. }

    扩展点注入Supplier

    1. public class SupplierBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    2. @Override
    3. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    4. BeanDefinition beanDefinition = beanFactory.getBeanDefinition("sua");
    5. GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanDefinition;
    6. genericBeanDefinition.setInstanceSupplier(OrgSupplier::create);
    7. genericBeanDefinition.setBeanClass(SuA.class);
    8. }
    9. }

    加入IOC容器

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans
    3. xmlns="http://www.springframework.org/schema/beans"
    4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    7. <bean id="sua" class="cn.lichenghao.supplier.SuA"/>
    8. <bean id="supplierBeanFactoryPostProcessor" class="cn.lichenghao.supplier.SupplierBeanFactoryPostProcessor"/>
    9. </beans>

    测试

    1. @DisplayName("自定义supplier")
    2. @Test
    3. public void supplierTest() {
    4. // 根据配置文件加载bean
    5. ClassPathXmlApplicationContext classPathXmlApplicationContext
    6. = new ClassPathXmlApplicationContext("supplier-test.xml");
    7. SuA bean = classPathXmlApplicationContext.getBean(SuA.class);
    8. System.out.println(bean);
    9. }

    然后打一个条件断点。
    image.png

    进入断点,发现我们的自定义 Supplier 已经成功加入。
    image.png

    接下来进入obtainFromSupplier方法创建对象即可。
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#obtainFromSupplier

    1. protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
    2. Object instance;
    3. String outerBean = this.currentlyCreatedBean.get();
    4. this.currentlyCreatedBean.set(beanName);
    5. try {
    6. instance = instanceSupplier.get();
    7. } finally {
    8. if (outerBean != null) {
    9. this.currentlyCreatedBean.set(outerBean);
    10. } else {
    11. this.currentlyCreatedBean.remove();
    12. }
    13. }
    14. if (instance == null) {
    15. instance = new NullBean();
    16. }
    17. BeanWrapper bw = new BeanWrapperImpl(instance);
    18. initBeanWrapper(bw);
    19. return bw;
    20. }