此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.2.0! |
使用@Configuration
注解
@Configuration
是类级注解,指示对象是
bean 定义。@Configuration
类通过@Bean
-注释
方法。调用@Bean
方法@Configuration
类还可用于定义
bean 间依赖关系。看基本概念:@Bean
和@Configuration
以获取一般介绍。
注入 bean 间依赖关系
当 bean 彼此依赖时,表达这种依赖性就很简单 就像让一个 bean 方法调用另一个 bean 方法一样,如下例所示:
-
Java
-
Kotlin
@Configuration
public class AppConfig {
@Bean
public BeanOne beanOne() {
return new BeanOne(beanTwo());
}
@Bean
public BeanTwo beanTwo() {
return new BeanTwo();
}
}
@Configuration
class AppConfig {
@Bean
fun beanOne() = BeanOne(beanTwo())
@Bean
fun beanTwo() = BeanTwo()
}
在前面的示例中,beanOne
接收对beanTwo
通过构造函数
注射。
这种声明 bean 间依赖关系的方法仅在@Bean 方法
在@Configuration 类。不能声明 bean 间依赖关系
通过使用 Plain@Component 类。 |
查找方法注入
如前所述,查找方法注入是一个 您应该很少使用的高级功能。它在 singleton 范围的 bean 依赖于原型范围的 bean。使用 Java 实现此目的 type 配置为实现此模式提供了一种自然的方法。这 以下示例显示了如何使用 Lookup 方法注入:
-
Java
-
Kotlin
public abstract class CommandManager {
public Object process(Object commandState) {
// grab a new instance of the appropriate Command interface
Command command = createCommand();
// set the state on the (hopefully brand new) Command instance
command.setState(commandState);
return command.execute();
}
// okay... but where is the implementation of this method?
protected abstract Command createCommand();
}
abstract class CommandManager {
fun process(commandState: Any): Any {
// grab a new instance of the appropriate Command interface
val command = createCommand()
// set the state on the (hopefully brand new) Command instance
command.setState(commandState)
return command.execute()
}
// okay... but where is the implementation of this method?
protected abstract fun createCommand(): Command
}
通过使用 Java 配置,您可以创建CommandManager
哪里
摘要createCommand()
方法被覆盖,以便它查找新的
(prototype) 命令对象。以下示例显示了如何执行此作:
-
Java
-
Kotlin
@Bean
@Scope("prototype")
public AsyncCommand asyncCommand() {
AsyncCommand command = new AsyncCommand();
// inject dependencies here as required
return command;
}
@Bean
public CommandManager commandManager() {
// return new anonymous implementation of CommandManager with createCommand()
// overridden to return a new prototype Command object
return new CommandManager() {
protected Command createCommand() {
return asyncCommand();
}
}
}
@Bean
@Scope("prototype")
fun asyncCommand(): AsyncCommand {
val command = AsyncCommand()
// inject dependencies here as required
return command
}
@Bean
fun commandManager(): CommandManager {
// return new anonymous implementation of CommandManager with createCommand()
// overridden to return a new prototype Command object
return object : CommandManager() {
override fun createCommand(): Command {
return asyncCommand()
}
}
}
有关基于 Java 的配置如何在内部工作的更多信息
请考虑以下示例,该示例显示了@Bean
带注释的方法被调用两次:
-
Java
-
Kotlin
@Configuration
public class AppConfig {
@Bean
public ClientService clientService1() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientService clientService2() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientDao clientDao() {
return new ClientDaoImpl();
}
}
@Configuration
class AppConfig {
@Bean
fun clientService1(): ClientService {
return ClientServiceImpl().apply {
clientDao = clientDao()
}
}
@Bean
fun clientService2(): ClientService {
return ClientServiceImpl().apply {
clientDao = clientDao()
}
}
@Bean
fun clientDao(): ClientDao {
return ClientDaoImpl()
}
}
clientDao()
已在clientService1()
和一次clientService2()
.
由于此方法会创建一个新的ClientDaoImpl
并返回它,您将
通常期望有两个实例(每个服务一个)。那肯定是
有问题的:在 Spring 中,实例化的 bean 有一个singleton
范围。这是
魔力所在:全部@Configuration
类在启动时被子类化
跟CGLIB
.在子类中,子方法首先检查容器是否有任何
在调用 Parent 方法并创建新实例之前缓存 (作用域) bean。
根据 Bean 的范围,行为可能会有所不同。我们正在交谈 关于单例 这里. |
没有必要将 CGLIB 添加到您的类路径中,因为 CGLIB 类已重新打包
在 |
由于 CGLIB 在
startup-time 的 Startup-time 中。特别是,配置类不能是 final。但是,任何
允许在配置类上使用构造函数,包括使用 如果您希望避免任何 CGLIB 施加的限制,请考虑声明您的 |