14. spring-容器: @Autowired, @Qualifier, @Primary, @Resource, @Inject注解

这些注解都是用于标识需要spring容器注入bean。

@Autowired, @Qualifier, @Primary是spring自带的注解
@Resource, @Inject是JSR 250注解,是javaee规范。spring进行了实现。

@Autowired

源码如下

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;

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
	boolean required() default true;
}

@Autowired注解说明

  • 该注解可以加在构造器,方法,方法参数,成员变量和注解上
  • 只有一个属性:required, 默认true。 当为true,DI找不到对应的bean时会抛出异常。
  • 默认优先按照类型去容器找对应的组件
  • 如果找到多个类型匹配的组件,再根据属性名称作为bean name去容器中查找
@Qualifier

配合@Autowired注解使用,当@Autowired想明确指定bean name时通过@Qualifier设置。

@Qualifier源码:

package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
	String value() default "";
}

@Qualifier因为跟@Autowired搭配使用,不会单独使用,所以能加注的地方跟@Autowired一致。

@Primary

当出现多个同类型的bean时,如果某个bean上加注了@Primary时,其他地方使用类型注入时会优先使用该bean。

源码如下:

package org.springframework.context.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;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Primary {

}

@Autowired, @Qualifier, @Primary综合示例
package win.elegentjs.spring.ioc.di.autowired;

import lombok.Data;

@Data
public class Bird {

    private String name;

}



package win.elegentjs.spring.ioc.di.autowired;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

/**
 * Person类注入两个field, 两个都使用@Autowired注入
 * 一个指定了bean name
 * 另一个未指定,按类型注入
 */
@Data
public class Person {

    @Autowired
    @Qualifier("bird")
    private Bird bird;

    @Autowired
    private Bird anotherBird;
}

定义java config类

package win.elegentjs.spring.ioc.di.autowired;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * java config配置类
 */
@Configuration
public class AutowiredConfig {

    /**
     * 定义bean name 为bird的bean
     */
    @Bean
    public Bird bird() {
        Bird b = new Bird();
        b.setName("鹦鹉");

        return b;
    }

    /**
     * 定义bean name 为bird2的bean,标注了@Primary。当按类型注入该bean时会优先注入
     */
    @Bean
    @Primary
    public Bird bird2() {
        Bird b = new Bird();
        b.setName("鹦鹉2");

        return b;
    }

    @Bean
    public Person person() {
        return new Person();
    }
}

执行看看结果:

package win.elegentjs.spring.ioc.di.autowired;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@Slf4j
public class AutowiredSample {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AutowiredConfig.class);

        Person p = context.getBean(Person.class);

        log.info("==> p: {}", p);
    }
}

// result:
2021-06-03 14:00:52.551 [main] INFO  w.e.spring.ioc.di.autowired.AutowiredSample-==> p: Person(bird=Bird(name=鹦鹉), anotherBird=Bird(name=鹦鹉2))

从结果可以看出当明确了bean name时会按匹配bean name的bean注入,当未指定明确的bean name时优先注入@Primary的bean。

@Resource

@Resource是 JavaEE JSR250标准规范的注解,默认按照bean name注入,bean name可以通过注入属性name指定,未指定默认按字段名查找。如果未指定name,且字段名作为bean name也找不到,才会按类型注入。

@Inject

@Inject注解是JSR330标准规范提供的注解,默认按照属性名查找bean, 支持@Primary。可以增加@Named注解指定注入的bean。

@Autowired vs @Resource vs @Inject
  • @Autowired时spring专有注解。@Resource是JSR规范,@Inject是JSR330规范
  • @Autowired支持required参数,其他两个不支持
  • @Autowired, @Inject支持@Primary优先注入功能,@Resource不支持
  • @Autowired搭配@Qulifier指定bean name, @Resource通过属性name指定,@Inject通过@Named注解支持

推荐统一使用@Autowired注解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值