Spring 5:以函数式方式注册 Bean

Spring 5 支持在应用程序上下文中以函数式方式注册 bean

简单地说,您可以通过在 GenericApplicationContext
类中定义的一个新的 registerBean()
方法重载来完成。

让我们来为此功能列举一些例子。

2、Maven 依赖

建立 Spring 5 项目的最快方式是将 spring-boot-start-parent
依赖添加到 pom.xml
中来使用 Spring Boot

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.M1</version>
    <relativePath/>
</parent>

我们的示例需要到 spring-boot-starter-web
spring-boot-starter-test
,且在 JUnit 测试中需要使用到 WebApplicationContext:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

当然,使用函数式的方式来注册一个 bean,Spring Boot 并不是必需的。 我们也可以直接添加 spring-core
依赖 [1]:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.0.0.RC2</version>
</dependency>

由于 Maven Central
仓库中尚未存在这些版本 [1],我们需要将 Spring Snapshot Repository
添加到 pom.xml
文件中:

<repositories>
    <repository>
        <id>spring-snapshot</id>
        <name>Spring Snapshot Repository</name>
        <url>https://repo.spring.io/snapshot</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

3、以函数式形式注册 Bean

registerBean() API 可以接收两种类型的函数式接口作为参数

  • 用于创建对象的 Supplier 参数
  • 一个 BeanDefinitionCustomizer vararg
    (可变参数),可用于提供一个或多个 lambda 表达式来自定义 BeanDefinition
    ;此接口有一个 custom()
    方法

首先,我们创建一个非常简单的类,使用它来创建 bean:

public class MyService{
    public int getRandomNumber(){
        return new Random().nextInt(10);
    }
}

我们再添加一个 @SpringBootApplication
类,可以使用它来运行 JUnit
测试:

@SpringBootApplication
public class Spring5Application{
    public static void main(String[] args){
        SpringApplication.run(Spring5Application.class, args);
    }
}

接下来,我们可以使用 @SpringBootTest
注解设置我们的测试类来创建一个 GenericWebApplicationContext
实例

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Spring5Application.class)
public class BeanRegistrationTest{
    @Autowired
    private GenericWebApplicationContext context;
    
    //...
}

我们在示例中使用了 GenericWebApplicationContext
类型,但任何类型的 ApplicationContext 都可以以相同的方式来注册一个 bean。

让我们看看如何 使用 lambda 表达式注册一个 bean 以创建实例

context.registerBean(MyService.class, () -> new MyService());

我们来验证一下可不可以检索到该 bean 并使用它:

MyService myService = (MyService) context.getBean("com.baeldung.functional.MyService"); 
  
assertTrue(myService.getRandomNumber() < 10);

在该例子中我们可以看到,如果没有明确定义 bean 的名称,那么它将根据小写的类名来确定。上述方法也可以与一个显式的 bean 名称一起使用:

context.registerBean("mySecondService", MyService.class, () -> new MyService());

接下来,让我们来看看 如何通过添加一个 lambda 表达式来自定义注册一个 bean

context.registerBean("myCallbackService", MyService.class, 
  () -> new MyService(), bd -> bd.setAutowireCandidate(false));

这个参数是一个函数式回调,我们可以使用它来设置 bean 属性,如 autowire-candidate
标志或 primary
标志。

4、结论

在本教程中,我们了解了如何以函数式方式来注册一个 bean。

该示例的源代码可以在 GitHub
上找到。

原文 

http://oopsguy.com/2017/10/02/spring-5-functional-beans/

PS:如果您想和业内技术大牛交流的话,请加qq群(527933790)或者关注微信公众 号(AskHarries),谢谢!

转载请注明原文出处:Harries Blog™ » Spring 5:以函数式方式注册 Bean

赞 (0)

分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址