疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

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


 

 
1、概述
 
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 上找到。