通过用户指定的 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 {
@Override
public 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"?>
<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-3.0.xsd">
<bean id="sua" class="cn.lichenghao.supplier.SuA"/>
<bean id="supplierBeanFactoryPostProcessor" class="cn.lichenghao.supplier.SupplierBeanFactoryPostProcessor"/>
</beans>
测试
@DisplayName("自定义supplier")
@Test
public void supplierTest() {
// 根据配置文件加载bean
ClassPathXmlApplicationContext 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;
}