Spring 中的 “自注入”

1、概览

自注入是指 Spring Bean 将自身作为依赖注入。它使用 Spring 容器获取自身的引用,然后使用该引用执行某些操作。

在这个简短的教程中,我们将了解如何在 Spring 中使用自注入。

2、自注入的场景

自注入最常见的用例是在需要将切面应用于自引用的方法或类时,绕过 Spring AOP 的限制

假设我们有一个执行某些业务逻辑的 service 类,需要调用自身的一个方法作为该逻辑的一部分:

@Service
public class MyService {
    public void doSomething() {
        // ...
        doSomethingElse();
    }

    @Transactional
    public void doSomethingElse() {
        // ...
    }
}

不过,当我们运行应用程序时,可能会发现 @Transactional 并未生效。这是因为 doSomething() 方法直接调用了 doSomethingElse(),从而绕过了 Spring 代理。

为了解决这个问题,我们可以使用自注入获取 Spring 代理的引用,然后通过该代理调用方法。

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 自注入

执行自注入的另一种方法是实现 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、缺点

当一个 Bean 使用自注入时,它可能会造成 Bean 职责的混乱,并使追踪应用程序中的调用流程变得更加困难。

自注入还可能创建循环依赖。从 2.6 版开始,如果我们的项目存在循环依赖,Spring Boot 就会抛出异常。当然,也有一些解决方法。

6、总结

在这篇短文中,我们了解了在 Spring 中使用自注入的几种方式以及应用场景。我们还了解了 Spring 自注入的一些缺点。


参考:https://www.baeldung.com/spring-self-injection