Spring IoC/DI 中接口使用 @Component 注解进行注解。可能是什么原因?

问题描述 投票:0回答:3

有时接口会使用@Component注解进行注解。那么我的明显推理是实现此类接口的类也将被视为组件。但如果我是对的,情况就不是这样了。

那么接口上@Component注解的用途是什么?

java spring dependency-injection inversion-of-control spring-ioc
3个回答
8
投票

使用

@Component
注释接口对于 Spring 类来说很常见,特别是对于一些 Spring 构造型注释 :

package org.springframework.stereotype;
...
@Component
public @interface Service {...}

或:

package org.springframework.boot.test.context;
...
@Component
public @interface TestComponent {...}

@Component
未声明为继承注释:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {...}

但是无论如何,在加载上下文期间,Spring 通过考虑候选类中声明的注释的层次结构来发现 bean。

在从底层源加载 bean 定义的

org.springframework.boot.BeanDefinitionLoader
类(包含在 Spring Boot 依赖项中)中,您可以看到以下示例
org.springframework.core.annotation.AnnotationUtils.findAnnotation()
Spring 用于检索整个注释层次结构中的注释:

class BeanDefinitionLoader {
 ...
 private boolean isComponent(Class<?> type) {
    // This has to be a bit of a guess. The only way to be sure that this type is
    // eligible is to make a bean definition out of it and try to instantiate it.
    if (AnnotationUtils.findAnnotation(type, Component.class) != null) {
        return true;
    }
    // Nested anonymous classes are not eligible for registration, nor are groovy
    // closures
    if (type.getName().matches(".*\\$_.*closure.*") || type.isAnonymousClass()
            || type.getConstructors() == null || type.getConstructors().length == 0) {
        return false;
    }
    return true;
 }
 ...
}

具体来说,这意味着由于

@Service
注解本身带有
@Component
注解,Spring会将带有
@Service
注解的候选类视为要实例化的bean。

所以,你的猜测是正确的:

实现此类接口的类将被视为组件 好吧。

但这仅适用于作为Java注释的接口(例如

@Service
),而不适用于普通接口

对于 Spring 类,这种做法是有意义的(例如丰富实际的构造型),但对于您自己的 bean,使用

@Component
作为接口而不是实现是行不通的,并且会带来更多的缺点而不是优点:

  • 它以同样的方式破坏了接口首先是契约的目的。它将它与 Spring 结合起来,并假设您将始终拥有该类的单个实现。
    既然如此,为什么还要使用接口呢?

  • 它将类的读取分散在两个地方,而接口不需要任何 Spring 构造型。


3
投票

事实并非如此,不需要在接口上添加@component,因为它不是一个bean,因为我们无法为它创建引用。 主要部分实际上是@autowired,您可以在其中注入依赖项。 例如

公共接口SortAlog(); 公共类 BubbleSortAlgo();

不,我们正在遵循动态绑定并创建接口对象,但实现是在运行时。

所以 @autowired 是在内部创建对象的那个,我们有 bubbleSortAlgo 的 @component 和注入的唯一候选者,所以它将从那里获取引用。

我希望我能够在这里表达自己的观点。


0
投票

我还在一些界面中使用了@component注释。主要原因是反向依赖注入。例如,我有两个项目,例如项目 A 和项目 B。项目 A 知道项目 B,但项目 B 不知道项目 A。在某些情况下,项目 B 需要向项目 A 发送一些消息,并且它通过以下接口发送这些消息:所以我对spring说有一个组件实现了我的接口,你会在初始化阶段找到并绑定它。

© www.soinside.com 2019 - 2024. All rights reserved.