@Autowired
UserService userService;
`@Autowired` 注解在使用 `Constructor Injection` 或者 `Setter Injection` 时会发生什么?实际上是进行了 `Field Injection`。不要求解释 IOC 或 DI 如何工作,只是询问 Spring Boot 中的 Field Injection 具体内部实现过程。
@Autowired
UserService userService;
基本上,字段注入是一种依赖注入类型(显然),因此Spring根据字段类型和可能的注释(如@Qualifier
)注入依赖项。
它是如何工作的?
当Spring创建一个Bean时,有一个特殊的Bean后置处理器org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
每个标记了@Autowired
的字段都被Spring视为一个依赖项,所以它必须分析这些依赖项(在底层使用反射)并为每个字段从应用程序上下文中找到匹配项(按类型、指定的限定符等)。然后它通过反射将值设置到字段中。
我不想在这里引发“神圣战争”,但我只想提到我个人尽量避免使用这种类型的注入,因为它会有效地破坏依赖项的封装性,使具有自动连线字段的类无法进行单元测试。例如,如果你有像这样的东西:
@Component
class Foo {
@Autowired
private Bar bar;
public Foo() {} // no-arg construction that exists by default
}
@Component
class Bar {
}
如果您自己创建Foo
实例(例如在单元测试中),您没有明确的方法向Foo
实例提供Bar
依赖项而不依赖于Spring。
例如,构造函数注入可以解决这个问题。