@Controller、@Service、@Repository、和 @Component 的效果是一样的,都是为了让Spring容器统一管理,主要是为了业务区分。
跟进源码看,其实都是@Component
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
再聊一下自动装配的注解。
1、@Autowired是自动注入中常用的注解,是按类型注入。由AutowiredAnnotationBeanPostProcessor这个后置处理器做处理。
源代码:省略部分注释
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* ....
* @author Juergen Hoeller
* @author Mark Fisher
* @since 2.5
* @see AutowiredAnnotationBeanPostProcessor
* @see Qualifier
* @see Value
*/
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}
由源代码可以看出它是Spring提供的注解,可以用于 构造器、成员方法、成员属性、也可用于注解,除此之外还可以设置非必须装配。
2、@Qualifier注解一般用于一个接口多个实现的情况,和@Autowired一起使用,可以指定装配Bean,英文意思为合格者
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
String value() default "";
}
3、@Resource注解是JAVA提供的,位于 javax.annotation包下 从部分代码可以看到该注解也是根据name指定注入Bean
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
/**
* The JNDI name of the resource. For field annotations,
* the default is the field name. For method annotations,
* the default is the JavaBeans property name corresponding
* to the method. For class annotations, there is no default
* and this must be specified.
*/
String name() default "";
...
}
翻译一下:对于字段注释,默认为字段名称。对于方法注释,默认为与该方法相对应的JavaBeans属性名称。对于类注释,没有默认,并且必须指定。
4、@Inject注解也是JAVA提供的,位于javax.inject包下,这个需要另外加入依赖,使用和@Autowired效果一致,从源码看区别不大
@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Inject {}
5、@Primary注解主要是设置Bean为最高优先级,是由Spring提供的注解,无法与Java的相关注解一起使用。使用此注解表示对于同一类型的Bean优先注入该注解标注的Bean。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Primary {
}
现在有两个问题,
1、如果我某个Bean组件在配置类中使用@Bean进行注入,同时使用了@Component注解对这个组件进行标记扫描,那么此时@Autowired注解注入的会是哪一个呢?
2、如果@Qualifier和@Primary 在同一个工程中使用,并且指定的Bean不一致,那么注入结果会什么样呢?