通过用户指定的 Supplier 来创建对象。我们可以在扩展点中给 bean 定义增加自定义的 Supplier。
// 通过给定的函数获取对象Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}
代码测试
public class SuA {private String name;public SuA() {}public SuA(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
自定义Supplier
public class OrgSupplier {public static SuA create() {return new SuA("Hello");}}
扩展点注入Supplier
public class SupplierBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition beanDefinition = beanFactory.getBeanDefinition("sua");GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanDefinition;genericBeanDefinition.setInstanceSupplier(OrgSupplier::create);genericBeanDefinition.setBeanClass(SuA.class);}}
加入IOC容器
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="sua" class="cn.lichenghao.supplier.SuA"/><bean id="supplierBeanFactoryPostProcessor" class="cn.lichenghao.supplier.SupplierBeanFactoryPostProcessor"/></beans>
测试
@DisplayName("自定义supplier")@Testpublic void supplierTest() {// 根据配置文件加载beanClassPathXmlApplicationContext classPathXmlApplicationContext= new ClassPathXmlApplicationContext("supplier-test.xml");SuA bean = classPathXmlApplicationContext.getBean(SuA.class);System.out.println(bean);}
然后打一个条件断点。
进入断点,发现我们的自定义 Supplier 已经成功加入。
接下来进入obtainFromSupplier方法创建对象即可。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#obtainFromSupplier
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {Object instance;String outerBean = this.currentlyCreatedBean.get();this.currentlyCreatedBean.set(beanName);try {instance = instanceSupplier.get();} finally {if (outerBean != null) {this.currentlyCreatedBean.set(outerBean);} else {this.currentlyCreatedBean.remove();}}if (instance == null) {instance = new NullBean();}BeanWrapper bw = new BeanWrapperImpl(instance);initBeanWrapper(bw);return bw;}
