在Spring5中对AbstractBeandefinition 添加了如下属性:
@Nullable private Supplier<?> instanceSupplier; /** * Specify a callback for creating an instance of the bean, * as an alternative to a declaratively specified factory method. * <p>If such a callback is set, it will override any other constructor * or factory method metadata. However, bean property population and * potential annotation-driven injection will still apply as usual. * @since 5.0 * @see #setConstructorArgumentValues(ConstructorArgumentValues) * @see #setPropertyValues(MutablePropertyValues) */ public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) { this.instanceSupplier = instanceSupplier; }根据其set方法的解释:就是替代工厂方法(包含静态工厂)或者构造器创建对象,但是其后面的生命周期回调不影响。
也就是框架在创建对象的时候会校验这个instanceSupplier是否有值,有的话,调用这个字段获取对象。
那么其应用场景什么呢?什么情况下使用呢?
静态工厂或者工厂方法或者构造器不足:
不管是静态工厂还是工厂方法,都需要通过反射调用目标方法创建对象,反射或多或少影响性能,如果不使用反射呢?
就是面向java8函数式接口编程,就是提供一个回调方法,直接调用回调方法即可,不需要通过反射了。
源码位置:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); }示例代码:
public class SupplierBean { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(User.class); beanDefinition.setInstanceSupplier(SupplierBean::createUser); context.registerBeanDefinition(User.class.getSimpleName(), beanDefinition); context.refresh(); System.out.println(context.getBean(User.class).getName()); } private static User createUser(){ return new User("小薇呀"); } static class User{ private String name; public User(String name) { this.name = name; } public String getName() { return name; } @PostConstruct public void init(){ System.out.println("user 初始化....."); } } }主要是考虑反射调用目标方法不如直接调用目标方法效率高。
