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

在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 初始化.....");
        }
    }
}

输出结果:

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

总结

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

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值