/** * 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) */ publicvoidsetInstanceSupplier(@Nullable Supplier<?> instanceSupplier){ this.instanceSupplier = instanceSupplier; }
/** * Return a callback for creating an instance of the bean, if any. * @since 5.0 */ @Nullable public Supplier<?> getInstanceSupplier() { returnthis.instanceSupplier; }
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); GenericBeanDefinition definition = new GenericBeanDefinition(); definition.setBeanClass(Book.class); definition.setInstanceSupplier((Supplier<Book>) () -> { Book book = new Book(); book.setName("深入浅出 Spring Security"); book.setAuthor("江南一点雨"); return book; }); ctx.registerBeanDefinition("b1", definition); ctx.refresh(); Book b = ctx.getBean("b1", Book.class); System.out.println("b = " + b);
publicclassBookSupplier{ public Book getBook(){ Book book = new Book(); book.setName("深入浅出 Spring Security"); book.setAuthor("江南一点雨"); return book; } }
然后调用这个方法即可:
1 2 3 4 5 6 7 8 9
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); GenericBeanDefinition definition = new GenericBeanDefinition(); definition.setBeanClass(Book.class); BookSupplier bookSupplier = new BookSupplier(); definition.setInstanceSupplier(bookSupplier::getBook); ctx.registerBeanDefinition("b1", definition); ctx.refresh(); Book b = ctx.getBean("b1", Book.class); System.out.println("b = " + b);
这是不是更有一点 Lambda 的感觉了~
在 Spring 源码中,处理获取 Bean 实例的时候,有如下一个分支,就是处理 Supplier 这种情况的: