java-在Spring IoC / DI中使用@Component注释对接口进行注释.可能是什么原因?
作者:互联网
有时,接口使用@Component注释进行注释.然后,我显而易见的理由是,实现此类接口的类也将被视为组件.但是,如果我是对的,那就不是这样.
那么接口上@Component注释的目的是什么.
解决方法:
在Spring类中,通常使用@Component注释接口,特别是对于某些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.
因此,您的猜测是正确的:
Classes that implement such interface will be treated as components as
well.
但这仅适用于Java注释的接口(例如@Service),不适用于普通接口.
对于Spring类,这种方式是有意义的(例如,丰富实际的构造型),但对于您自己的bean,将@Component用作接口而不是实现将不起作用,并且带来的弊大于利:
>它以同样的方式破坏了首先是合同的接口的目的.它将其耦合到Spring,并假设您将始终拥有该类的单个实现.在这种情况下,为什么要使用接口?
>它将类的读取分散在两个位置,而接口不需要任何Spring构造型.
标签:java,spring,dependency-injection,inversion-of-control,spring-ioc 来源: https://codeday.me/bug/20191012/1903753.html