有时,接口会使用@Component注释进行注释。然后我明显的推理是,实现这种接口的类也将被视为组件。但如果我是对的,事实并非如此。
那么接口上@Component注释的目的是什么。
答案 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,并且是注入的唯一候选对象,因此它将从那里获得引用。
我希望我能在这里指出一点。