1、概览 {#1概览}
自注入是指 Spring Bean 将自身作为依赖注入。它使用 Spring 容器获取自身的引用,然后使用该引用执行某些操作。
在这个简短的教程中,我们将了解如何在 Spring 中使用自注入。
2、自注入的场景 {#2自注入的场景}
自注入最常见的用例是在需要将切面应用于自引用的方法或类时,绕过 Spring AOP 的限制
假设我们有一个执行某些业务逻辑的 service 类,需要调用自身的一个方法作为该逻辑的一部分:
@Service
public class MyService {
public void doSomething() {
// ...
doSomethingElse();
}
@Transactional
public void doSomethingElse() {
// ...
}
}
不过,当我们运行应用程序时,可能会发现 @Transactional
并未生效。这是因为 doSomething()
方法直接调用了 doSomethingElse()
,从而绕过了 Spring 代理。
为了解决这个问题,我们可以使用自注入获取 Spring 代理的引用,然后通过该代理调用方法。
3、使用 @Autowired
自注入 {#3使用-autowired-自注入}
在 Spring 中,我们可以通过在 Bean 的字段、构造器参数或 setter 方法上使用 @Autowired
注解来进行自注入。
下面是一个在字段上使用 @Autowired
的示例:
@Component
public class MyBean {
@Autowired
private MyBean self;
public void doSomething() {
// 在这里使用 self 引用
}
}
通过构造器参数自注入。
@Component
public class MyBean {
private MyBean self;
@Autowired
public MyBean(MyBean self) {
this.self = self;
}
// ...
}
4、使用 ApplicationContextAware
自注入 {#4使用-applicationcontextaware-自注入}
执行自注入的另一种方法是实现 ApplicationContextAware
接口。该接口允许 Bean 感知 Spring application context,并获取自身的引用:
@Component
public class MyBean implements ApplicationContextAware {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
public void doSomething() {
MyBean self = context.getBean(MyBean.class);
// ...
}
}
5、缺点 {#5缺点}
当一个 Bean 使用自注入时,它可能会造成 Bean 职责的混乱,并使追踪应用程序中的调用流程变得更加困难。
自注入还可能创建循环依赖。从 2.6 版开始,如果我们的项目存在循环依赖,Spring Boot 就会抛出异常。当然,也有一些解决方法。
6、总结 {#6总结}
在这篇短文中,我们了解了在 Spring 中使用自注入的几种方式以及应用场景。我们还了解了 Spring 自注入的一些缺点。
参考:https://www.baeldung.com/spring-self-injection