Spring 5 Functional Bean Registration – Spring 5 函数 Bean 的注册

最后修改: 2017年 8月 28日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Spring 5 comes with support for functional bean registration in the application context.

Spring 5支持应用程序上下文中的功能Bean注册。

Simply put, this can be done through overloaded versions of a new registerBean() method defined in the GenericApplicationContext class.

简单地说,这可以通过GenericApplicationContext类中定义的新的registerBean()方法的重载版本完成。

Let’s have a look at a few examples of this functionality in action.

让我们来看看这个功能的几个实际例子。

2. Maven Dependencies

2.Maven的依赖性

The quickest way to setup a Spring 5 project is to use Spring Boot by adding the spring-boot-starter-parent dependency to the pom.xml:

设置Spring 5项目的最快方法是使用Spring Boot,方法是将spring-boot-starter-parent依赖性添加到pom.xml:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
</parent>

We also need the spring-boot-starter-web and spring-boot-starter-test for our example, to use a web application context in a JUnit test:

我们还需要spring-boot-starter-webspring-boot-starter-test为我们的例子,在JUnit测试中使用Web应用程序上下文。

<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>

Of course, Spring Boot is not necessary in order to use the new functional way to register a bean. We could also just add the spring-core dependency directly:

当然,Spring Boot并不是使用新的功能方式来注册Bean的必要条件。我们也可以直接添加spring-core的依赖关系。

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

3. Functional Bean Registration

3.功能Bean注册

The registerBean() API can receive two types of functional interfaces as parameters:

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

  • a Supplier argument used to create the object
  • a BeanDefinitionCustomizer vararg which can be used to provide one or more lambda expressions to customize the BeanDefinition; this interface has a single customize() method

First, let’s create a very simple class definition that we will use to create beans:

首先,让我们创建一个非常简单的类定义,我们将用它来创建bean。

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

Let’s also add a @SpringBootApplication class that we can use to run a JUnit test:

让我们也添加一个@SpringBootApplication类,我们可以用它来运行一个JUnit测试。

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

Next, we can set up our test class using the @SpringBootTest annotation to create a GenericWebApplicationContext instance:

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

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

We’re using the GenericWebApplicationContext type in our example, but any type of application context can be used in the same way to register a bean.

在我们的例子中,我们使用的是GenericWebApplicationContext类型,但任何类型的应用程序上下文都可以用同样的方式来注册Bean。

Let’s see how we can register a bean using a lambda expression for creating the instance:

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

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

Let’s verify that we can now retrieve the bean and use it:

让我们验证一下,我们现在可以检索到Bean并使用它。

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

We can see in this example that if the bean name isn’t explicitly defined, it will be determined from the lower-case name of the class. The same method above can also be used with an explicit bean name:

在这个例子中我们可以看到,如果Bean的名字没有明确定义,它将由类的小写名字决定。上面的方法也可以用在明确的bean名称上。

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

Next, let’s see how we can register a bean by adding a lambda expression to customize it:

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

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

This argument is a callback that we can use to set bean properties such as autowire-candidate flag or primary flag.

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

4. Conclusion

4.结论

In this quick tutorial, we’ve seen how we can use the functional way of registering a bean.

在这个快速教程中,我们已经看到了如何使用功能化的方式来注册Bean。

The source code for the example can be found over on GitHub.

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