接口在Spring IoC / DI中使用@Component注释进行注释。可能是什么原因? [英] Interfaces are annotated with @Component annotation in spring IoC/DI. What could be the reason?

查看:262
本文介绍了接口在Spring IoC / DI中使用@Component注释进行注释。可能是什么原因?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Some times interfaces are annotated with @Component annotation. Then my obvious reasoning was that classes that implement such interface will be treated as components as well. But if I am right that is not the case.

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

So what is the purpose of @Component annotation on interfaces.

推荐答案

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

Annotating an interface with @Component is common for Spring classes, particularly for some Spring stereotype annotations :

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

或:

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

@Component 未声明为继承的注释:

@Component is not declared as an inherited annotation :

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

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

But whatever, during loading of the context, Spring discovers beans by considering the hierarchy of the annotation declared in the candidate class.

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

In the org.springframework.boot.BeanDefinitionLoader class (included in the Spring Boot dependency) that loads bean definitions from underlying sources, you can see an example of org.springframework.core.annotation.AnnotationUtils.findAnnotation() that Spring uses to retrieve annotations in the whole hierarchy of the annotation:

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会考虑用<$ c $注释的候选类c> @Service 作为实例化的bean。

Concretely, it means as the @Service annotation is itself annotated with @Component, Spring will consider a candidate class annotated with @Service as a bean to instantiate.

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

So, your guesswork is right :


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

Classes that implement such interface will be treated as components as well.

但这仅适用于Java注释的接口(例如 @Service ),而不适用于普通接口

But this works only for interfaces (such as @Service) that are Java annotations and not for plain interfaces.

对于Spring类,这种做法很有意义(例如丰富实际的构造型)但对于你自己的bean,使用 @Component 对于接口而不是实现将无法工作,并将带来更多的缺点而不是优势:

For Spring classes, this way of doing makes sense (enriching actual stereotype for example) but for your own beans, using @Component for the interface rather than the implementation will not work and would bring more drawbacks than advantages :


  • 它以同样的方式失败上面的接口的目的所有的合同。它将它耦合到Spring,它假设您将始终只有一个类的实现。
    在这种情况下,为什么要使用界面?

  • it defeats in a same way the purpose of an interface that is above all a contract. It couples it to Spring and it supposes that you will always have a single implementation of the class.
    In this case, why using an interface ?

它会在两个位置分散类的读取,而界面不需要任何春天刻板印象。

it scatters the reading of the class at two places while the interface doesn't need to have any Spring stereotype.

这篇关于接口在Spring IoC / DI中使用@Component注释进行注释。可能是什么原因?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆