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-web和spring-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上找到。