Spring 源码分析之@Autowired 深入解读

@Autowired 源码分析

/*
 * @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;
}

@Autowired标注在构造方法,字段,setter方法,或者是能够被Spring依赖注入的配置方法。可以选择使用JSR-330 javax.inject.Inject注解,添加了required-vs-optional的语义。

  • Autowired Constructors

    在任何给定bean类中,只有一个构造方法可以将required属性设置为true来声明这个注释,以指示在作为Spring bean使用时要自动装配的构造方法。

    此外,如果required属性被设置为true,那么只有一个构造方法可以用@Autowired注解。如果多个非必需的构造方法标识该注解,那么它们将被视为自动装配的候选构造方法。

    通过在Spring容器中匹配bean可以满足的依赖关系最多的构造方法将被选择。

    如果不存在满足匹配的候选构造方法,则将会使用primary/default 构造方法(如果存在的话)。

    如果类只声明了一个构造方法,那么该构造方法总是会被使用的,尽管并没有标注@Autowired。带注释的构造方法不必是public的。

  • Autowired Fields

    字段是在构建bean之后,在调用任何配置方法之前注入的。

    这样的配置字段不必是public的。

  • Autowired Methods

    Config methods may have an arbitrary name and any number of arguments; each of those arguments will be autowired with a matching bean in the Spring container. Bean property setter methods are effectively just a special case of such a general config method. Such config methods do not have to be public.

    配置方法可以有任意名称和任意数量的参数。

    这些参数中的每一个都将通过匹配到Spring容器中的bean来注入。

    Bean属性setter方法实际上只是这种通用配置方法的一个特例。

    这样的配置方法不必是public的。

  • Autowired Parameters

  • Multiple Arguments and ‘required’ Semantics

  • Autowiring Arrays, Collections, and Maps

多个同类型的Bean,直接使用@Autowired时

@Controller
public class OrderController {
    @Autowired
    private Coffee coffee2;
}
@Bean
public Coffee coffee() {
    return new Coffee("1");
}

@Bean("coffee2")
public Coffee coffee02() {
    return new Coffee("Coffee-02");
}
  • 如果存在多个同类型的Bean实例,需要注意的是,在使用@Autowired注入时,会根据字段的名称去容器中找实例。所以,OrderController注入的是coffee2实例。

@Primary与@Bean,@Autowired搭配使用

@Controller
public class OrderController {
    /**
     * 使用@Qualifier("coffee2")就可以做到即便存在多个相同类型的Bean,也不需要根据Bean的id来调整字段的名称。
     * 保持我们想要的字段名称,通过@Qualifier来指定多个相同类型Bean实例的具体实例。
     *
     * 注解@Autowired(required = false),required的设置仅在容器中没有对应的类型Bean才有效
     * 如果存在多个相同类型的Bean,导致的无法正确注入Bean,是不会触发required的生效的。
     */
    @Autowired
    private Coffee coffee3;
}
@Bean
public Coffee coffee() {
    return new Coffee("1");
}

@Primary
@Bean("coffee2")
public Coffee coffee02() {
    return new Coffee("Coffee-02");
}
  • 此时Controller,即便字段名为coffee3,同时容器里存在多个同类型的Bean,但也能正确注入Coffee实例,注入的实例为标识有@Primary的Bean。

总结

@Autowired,构造方法,方法参数,方法,字段都能从容器中获取到对应的值。

  • 1)、默认优先按照类型去容器中找对应的组件,byType

  • 2)、如果存在多个同类型的组件,会将字段的名称作为组件的id去容器中获取,byName

  • 3)、注解@Autowired(required = false),required的设置仅在容器中没有对应的类型Bean才有效。

    如果存在多个相同类型的Bean,导致的无法正确注入Bean,是不会触发required的生效的。

  • 4)、如果只存在一个有参构造,那么该有参构造的@Autowired可以省略。

@Qualifier,指定需要注入的组件的id,而不是使用字段名来获取注入

  • 使用@Qualifier(“coffee2”)就可以做到即便存在多个相同类型的Bean,也不需要根据Bean的id来调整字段的名称。
  • 保持我们想要的字段名称,通过@Qualifier来指定多个相同类型Bean实例的具体实例。
  • 当一个接口有多个实现的时候,用于指明具体注入哪个实现类。

@Primary,让Spring进行自动装配时,默认使用首选的Bean。

  • 多与@Bean结合使用。

@Resource

  • 和@Autowired效果一样,能够实现Bean的自动装配。

    默认是按照Bean名称进行装配,byName

    没有能支持@Primary的功能,也不能像@Autowired那样可以设置required值。

@Inject

  • 需要导入javax.inject依赖包,和@Autowired效果一样,但同样没有可以设置required值的功能。

@Autowired是Spring定义的,@Resource和@Inject属于Java规范。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值