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

时间:2017-09-30 11:53:49

标签: java spring dependency-injection inversion-of-control spring-ioc

有时,接口会使用@Component注释进行注释。然后我明显的推理是,实现这种接口的类也将被视为组件。但如果我是对的,事实并非如此。

那么接口上@Component注释的目的是什么。

2 个答案:

答案 0 :(得分:1)

使用@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。

org.springframework.boot.BeanDefinitionLoader类(包含在Spring Boot依赖项中)从底层源加载bean定义,你可以看到一个例子 Spring使用org.springframework.core.annotation.AnnotationUtils.findAnnotation()来检索注释的整个层次结构中的注释:

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构造型。

答案 1 :(得分:0)

不是这种情况,不需要在接口上添加@component,因为它不是bean,因为我们无法为其创建引用。 实际上,主要部分是@autowired,在其中注入依赖项。 例如

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

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

所以@autowired是在内部创建对象的那个,我们为bubbleSortAlgo提供了@component,并且是注入的唯一候选对象,因此它将从那里获得引用。

我希望我能在这里指出一点。