当前位置: 代码迷 >> 综合 >> Spring5 BeanDefinition 中Supplier<?> instanceSupplier属性的应用场景
  详细解决方案

Spring5 BeanDefinition 中Supplier<?> instanceSupplier属性的应用场景

热度:65   发布时间:2024-03-07 08:37:31.0

在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;}@PostConstructpublic void init(){System.out.println("user 初始化.....");}}
}

输出结果:

user 初始化.....
小薇呀

总结

主要是考虑反射调用目标方法不如直接调用目标方法效率高。