为什么我们要使用 @Autowire
为什么我们要使用 @Autowire
我对Spring还很陌生,对它的理解非常肤浅,但是,假设我们看以下示例:
class serviceImpl implements service{ @Autowired private Mapper mapper; public void executeService(){ mapper.executeSerice(); } }
所以,我正在尝试构建一些服务,该服务从持久层调用Mapper。`Mapper`是一个抽象类。所以根据我的理解,使用`@Autowired`会自动注入一个`Mapper`的实现。
那么我的问题是:
- 如果有多个`Mapper`的实现,该怎么办?经过一些搜索,似乎在这种情况下,需要使用`@Qualifier`来指定要使用的实现。
- 假设我们正在使用实现`powerfulMapper`,那么我们将需要使用`@Qualifier('powerfulMapper')`。
那么,这与在这里实例化`Mapper powerfulMapper`有什么不同?
为什么我们使用@Autowired?
在Spring中,当我们有多个Mapper实现类被注册为Spring bean时,我们必须使用@Autowired或@Qualifier来告诉Spring要注入哪个实现类。如果只有一个Mapper实现类,我们只需要使用@Autowired进行注入即可。
那么,为什么不直接实例化Mapper类呢?
区别在于,如果一个类是Spring bean,我们可以在其上应用一些Spring特性,例如:
- 应用AOP(面向切面编程)功能,如@Before、@After等。
- 考虑一种情况,如果一个类有很多依赖关系,并且这些依赖关系又有很多依赖关系,手动创建整个依赖图配置的实例化过程是一件麻烦的事情。更不用说不同的依赖关系可能有不同的要求(例如,一个可能需要作为单例实例化,并且可以被不同的类共享使用,而另一个可能需要在原型作用域下,不同的类需要一个单独的实例等)。
使用@Autowired并让Spring配置这样的依赖关系图要比手动实现更容易。
另一方面,如果Mapper只有非常简单的依赖关系,只在ServiceImpl内部使用,并且不需要Spring提供的任何好处,您可以将其简单地实例化,而无需将其声明为Spring bean。
非常感谢您的回答,但是您所说的“配置整个依赖关系图”是什么意思?
这意味着为了创建一个具有一些强制依赖关系(例如ClassA)的对象(例如Mapper),您必须首先实例化ClassA。因此,如果ClassA有其他强制依赖关系(例如ClassB),您必须先创建ClassB,然后才能创建ClassA。如果ClassB又有其他依赖关系(例如ClassC),您必须在创建ClassB之前创建ClassC,依此类推。这些依赖关系可以想象成一个图形。
但是,假设A依赖于B,B依赖于C,B对C的依赖关系已经在B中内置,当我创建A时,我似乎不需要担心那个依赖关系。而且,即使我使用依赖注入,如果我曾经更改接口C中的函数,似乎我仍然需要修改使用C的所有内容。
为什么我们使用@Autowire?
使用依赖注入(DI)是为了避免出现复杂的依赖关系树。假设有一个树形结构,其中A实例化类B,类B实例化类C,然后A实例化类D,类D实例化类E。
A --> B --> C
\
--> D --> E
这一切都很好,直到类E需要类C为止。然后我们需要重新安排所有的东西,并在更高的位置实例化C,然后通过类B和类D传递给两边。
这就是依赖注入(DI)发挥作用的地方。
我们决定让A实例化所有的类:
A --> B
--> C
--> D
--> E
所以A是所有类的所有者,他可以将任何类传递给任何类,以满足任何类的需求。
这就是Spring上下文与@Autowired注解的作用。您告诉Spring您希望哪个类被传递给实例化的类。然后,在启动过程中,Spring将实例化所有类,并确定哪个类应该放在哪个位置(这是一个非常简化的过程)。所有的类默认都将被实例化为单例(但可以自定义)。
当Spring实例化您的类时,它被称为Spring托管的bean。Spring管理它的生命周期,而不是您,因为您没有使用new关键字,而是使用了框架。
在此过程中,Spring进行了一系列的检查,并按特定的顺序进行实例化,首先是配置类,然后是注解类,最后是其他类(这里过于简化了),它会扫描应该实例化的类,决定首先实例化哪些类,然后将哪些类注入到哪些类中。在此阶段,有一些辅助注解可以帮助Spring。
@Autowired就是其中之一,您可以给出一个类的名称,然后告诉Spring您希望它在哪个位置进行注入。
如果您配置了两个不同的单例,但它们具有相同的名称,这将非常有用。
为什么我们要使用 @Autowire?
在Java开发中,我们经常会遇到依赖注入的需求。依赖注入是一种设计模式,通过将组件的依赖关系从代码中解耦,可以提高代码的可维护性和可测试性。Spring框架为我们提供了 @Autowire 注解,可以方便地实现依赖注入。
如果我们想要在不同的实现之间切换,就需要使用 @Autowire 注解。假设我们有两个不同的实现,一个使用 "powerfulMapper",另一个使用 "notAPowerfulMapper"。在使用 @Autowire 注解时,我们还需要指定要注入的实现,例如:
@Autowire("powerfulMapper") private Mapper mapper;
这样,Spring框架就会自动将 "powerfulMapper" 注入到 mapper 变量中。
通过使用 @Autowire 注解,我们可以轻松实现依赖注入,而无需手动创建对象或解决对象之间的依赖关系。这样一来,我们可以更加专注于业务逻辑的实现,提高开发效率。
总结起来,我们使用 @Autowire 的原因是为了实现依赖注入,将组件的依赖关系从代码中解耦。通过指定要注入的实现,我们可以轻松切换不同的实现。通过使用 @Autowire 注解,我们可以提高代码的可维护性和可测试性,提高开发效率。
希望这篇文章对你理解为什么我们要使用 @Autowire 有所帮助。如果你有任何问题,请随时向我提问。