SpringBoot 依赖注入

前言

SpringBoot 中通过注解实现依赖注入主要有以下几种:

@Autowired注解

@Qualifier注解

@Resource注解

@Primary注解

@Autowired: 注入依赖对象

简介

作用

实现依赖注入

查找方式

@Autowired是先到容器查找类型,如果该类型只有一个那么就直接注入,有多个时再根据名字找

使用范围

构造器、方法、参数、字段、注解

参数

required -> 标注的对象是否必须注入,可能这个对象在容器中不存在,如果为true的时候,找不到匹配的候选者就会报错,为false的时候,找不到也没关系,不会报错

定义

@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; 
}
CONSTRUCTOR:构造
METHOD:方法
PARAMETER:参数
FIELD:字段
ANNOTATION_TYPE: 注解

使用示例

1、用于构造方法

将@Autowired注解应用于构造函数,通过构造器注入依赖对象

public class Service {
    private Service1 service1;
    
    public Service(){
        System.out.println(this.getClass() + "无参构造器");
    }

    @Autowired
    public Service(Service1 service1){
    		System.out.println(this.getClass() +"有参构造器");
        this.service1 = service1;
    }
}

2、用于普通方法

将@Autowired标注在方法,spring从容器中查找方法参数相关的bean,然后注入依赖的对象,如果该方法有多个参数,默认多个参数都可以自动注入依赖

@Component
public class Service {

    private Service1 service1;
  
  	private Service2 service2;

    @Autowired
    public void injectService1(Service1 service1){
        this.service1 = service1;
    }
  
    @Autowired
    public void injectService1(Service1 service1, Service2 service2){
        this.service1 = service1;
        this.service2 = service2;
    }
}

3、用于setter方法

可能通过构造器,和通过普通的一个方法注入,这两种方式不是很常见,可以将@Autowired标注在set方法上面来注入指定的对象,如下所示

@Component
public class Service {

    private Service1 service1;

    @Autowired
    public void setService1(Service1 service1){
        this.service1 = service1;
    }
}

4、用于方法参数上

@Autowired直接标注于方法的具体参数上,在多个参数的时候,方法上面的@Autowired默认对方法中所有的参数起效,如果我们想对其中某个参数进行特定的配置,则有以下两种方法实现:

1、可以在需依赖注入的参数前面加上@Autowired,就能实现自动依赖注入。

@Component
public class Service {

    private Service1 service1;
    private String name;
  
    public void injectService(@Autowired Service1 service1, String name){
        this.service1 = service1;
        this.name = name;
    }

此时方法的第一个参数则受到@Autowired约束,而第二个参数则不受约束

2、在不需要强制注入的参数前面加@Autowired,并设置required为false,这样则表示这个bean不是强制注入,能找到相应的bean就注入,找不到的话就注入一个null对象,如下 :

@Component
public class Service {

    private Service1 service1;

    private String name;

    @Autowired
    public void injectService(Service1 service1, @Autowired(required = false) String name){
        this.service1 = service1;
        this.name = name;
    }
}

此时方法的第一参数被上面的@Autowired约束,第二个参数受@Autowired(required=false)约束

5、用于字段上

@Autowired直接标注于具体的字段,则会自动进行依赖注入,Spring会去容器中按照类型查找相关类型的bean,然后将设置到相应的属性。

@Component
public class Service {

    @Autowired
    private Service1 service1;
}

6、用于Collection、Map中

1、注入到Collection中,被注入的类型为Collection类型或者Collection子接口类型,注意必须是接口类型

Collection<IService> 
List<IService> 
Set<IService>

2、注入到Map中,被注入的类型为Map类型或者Map子接口类型,注意必须是接口类型

Map<String,IService>

示例如下:

下面分别先定义一个接口,两个接口的实现类

public interface IService {
}

@Component 
public class Service1 implements IService { 
}

@Component 
public class Service2 implements IService { 
}

@Component 
public class Service { 

  @Autowired 
  private List<IService> services;  //@1
  
  @Autowired 
  private Map<String, IService> serviceMap;  //@2
  
}

@1: 注入IService类型的所有bean
@2: 注入一个map

@Resource:注入依赖对象

简介

作用

和@Autowired注解类似,也是用来注入依赖对象的,spring容器会对bean中所有的字段、方法进行遍历,标注有@Resouce注解的,都会进行注入。@Autowired是在javax中定义的注解,并不是spring中定义的注解。

查找方式

@Resource是先到容器按照名字查找,同一名字只有一个则直接注入,同名不同类时则再按照类型查找。

使用范围

任何类型、字段、方法

定义

@Target({TYPE, FIELD, METHOD}) 
@Retention(RUNTIME) 
public @interface Resource { 
  String name() default "";
  ..其他不常用的参数省略 
}

使用示例

1、用于字段

@Component 
public class Service2 { 
 
  @Resource 
  private Service1 service1;
  
}

2、用于方法

@Component
public class Service {

    private Service1 service1;

    @Resource
    public void setService1(Service1 service1){
        this.service1 = service1;
    }
}

3、用于Collection、Map中

1、注入到Collection中,被注入的类型为Collection类型或者Collection子接口类型,注意必须是接口类型

Collection<IService> 
List<IService> 
Set<IService>

2、注入到Map中,被注入的类型为Map类型或者Map子接口类型,注意必须是接口类型

Map<String,IService>

下面分别先定义一个接口,两个接口的实现类

public interface IService {
}

@Component 
public class Service { 

	@Resource 
  private List<IService> services;  //@1
  
  @Resource 
  private Map<String, IService> serviceMap;  //@2
  
}

@1: 注入IService类型的所有bean
@2: 注入一个map

@Qualifier: 限定符

简介

作用

可以在依赖注入查找候选者的过程中对候选者进行过滤,比如:在需要自动注入java bean时,如果注入的是一个接口,而这个接口又有多个实现类,则会报错,解决方法是在注入接口上增加@Qualifier(“别名”) 和@Autowired注解,

使用范围

字段、方法、参数、任意类型、注解

参数

value

定义

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) 
@Inherited 
@Documented 
public @interface Qualifier { 
	String value() default ""; 
}

使用示例

1、用于类上

用在类上,你可以理解为给通过@Qulifier给这个bean打一个标签

public interface IService { }

@Component 
@Qualifier("tag1") //@1 
public class Service1 implements IService{ }

@1: 设置@Qulifier的value为tag1

@Component 
@Qualifier("tag2") //@2
public class Service2 implements IService { }

@2: 设置@Qulifier的value为tag2

@Component 
@Qualifier("tag3") //@3
public class Service3 implements IService { }

@3: 设置@Qulifier的value为tag3

@Component 
public class InjectService { 
  
  @Autowired 
  @Qualifier("tag1") //@1 
  private Map<String, IService> serviceMap1; 
  
  @Autowired 
  @Qualifier("tag2") //@2 
  private Map<String, IService> serviceMap2;    
  
  @Autowired 
  @Qualifier("tag3") //@3
  private Map<String, IService> serviceMap3;
}

@1: 限定符的值为tag1,此时会将类上限定符为tag1的所有bean注入进来
@2: 限定符的值为tag2,此时会将类上限定符为tag2的所有bean注入进来
@3: 限定符的值为tag3,此时会将类上限定符为tag3的所有bean注入进来

2、结合@Autowired使用

我们先定义一个接口,以及两个实现类,分别是Servicr1和Service2

public interface IService { }

@Component 
@Qualifier("service1")
public class Service1 implements IService{ }

@Component 
@Qualifier("service2")
public class Service2 implements IService { }

@Component 
public class InjectService { 

  @Autowired 
  @Qualifier("service2") //@1 
  private IService service; 	
}

@1: 这里限定符的值为service2,容器中IService类型的bean有2个【service1,service2】,当类上没有标注@Qualifier注解的时候,可以理解为:bean的名称就是限定符的值,所以@1这里会匹配到service2

3、用于方法参数

public interface IService { }

@Component 
@Qualifier("service1")
public class Service1 implements IService{ }

@Component 
@Qualifier("service2")
public class Service2 implements IService { }

@Component 
public class InjectService { 

	private IService s1; 
	
	private IService s2; 
	
	@Autowired 
	public void injectBean(@Qualifier("service2") IService s1, @Qualifier("service1") IService s2) { //@1 
		this.s1 = s1; 
		this.s2 = s2; 
	}	
}

@1: 方法上标注了@Autowired注解,说明会被注入依赖,2个参数上分别使用了限定符来指定具体需要注入哪个bean

4、用在setter方法上

不管是用在setter方法还是普通方法上面,都是一样的效果

public interface IService { }

@Component 
@Qualifier("service1")
public class Service1 implements IService{ }

@Component 
@Qualifier("service2")
public class Service2 implements IService { }

@Component 
public class InjectService { 
  
  private IService s1; 
  
  private IService s2; 
  
  @Autowired 
  @Qualifier("service2") 
  public void setS1(IService s1) { 
    this.s1 = s1; 
  }
  
  @Autowired 
  @Qualifier("service1") 
  public void setS2(IService s2) { 
    this.s2 = s2; 
  } 
}

上面2个setter方法上都有@Autowired注解,并且结合了@Qulifier注解来限定需要注入哪个bean

@Primary: 设置为主要候选者

简介

作用

在注入依赖的过程中,当有多个候选者的时候,可以指定哪个候选者为主要的候选者。可以用在类上或者方法上面。通常定义bean常见的有2种方式:
1、在类上标注@Component注解,此时可以配合@Primary,标注这个bean为主要候选者。
2、在配置文件中使用@Bean注解标注方法,来注册bean,可以在@Bean标注的方法上加上@Primary,标注这个bean为主要候选bean。

使用范围

类、方法

参数

value

定义

@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) 
@Documented 
public @interface Primary { }

使用示例

1、用于类上

public interface IService { }

@Component 
public class Service1 implements IService{ }

@Component 
@Primary //此处使用了@Primary,表示这是个主要候选者
public class Service2 implements IService { }

@Component 
public class InjectService { 

	@Autowired 
	private IService service1; //@1
}

@1: 容器中IService类型的bean有2个,但是service2为主要候选者,所以此处会注入service2

2、用于方法上

public interface IService { }

//注意,这个类没有标注@Component 注解的,表明这个类并非是自动依赖注入
public class Service1 implements IService { }

//注意,这个类没有标注@Component 注解的,表明这个类并非是自动依赖注入
public class Service2 implements IService { } //注意,这个类没有标注@Component 注解的,表明这个类并非是自动依赖注入
//该类为一个配置类,主要是通过定义Bean注解来实现相关类的依赖注入
@Configuration 
public class ServiceConfig{ 

	@Bean 
	public IService service1() { 
		return new Service1(); 
	}
	
	@Bean 
	@Primary //这个bean被标注为主要的候选者
	public IService service2() { 
		return new Service2(); 
	} 
}
public class InjectService { 
  
	@Autowired 
	private IService service;//@1
	
}

@1:IService为两个实现类,同进在ServiceConfig中,两个实现类Service1、Service2都实现在依赖注入,而此时由于Service2的bean使用了@Primary注解,因此在查找到多个Bean时,会优化选择有@Primary标注的bean进行注入,所以在这里service注入的值是Service2

原创文章,作者:jiafegn,如若转载,请注明出处:https://www.techlearn.cn/archives/2018

Previous 2024年1月11日
Next 2024年1月25日

相关推荐

  • Springboot 注解大全-@Import

    作用 @Import可以用来批量导入需要注册的各种类,如普通的类、配置类,完成普通类和配置类中所有bean注册到spring容器中。作用范围:作用于类、注解 定义 参数 value…

    springboot 2022年8月15日
    184
  • SpringBoot 注解 @Autowired

    作用 实现依赖注入查找方式:@Autowired是先到容器查找类型,如果该类型只有一个那么就直接注入,有多个时再根据名字找使用范围:构造器、方法、参数、字段、注解参数:requir…

    springboot 2022年9月9日
    405
  • SpringBoot 整合Redis

    添加依赖 在pom.xml文件添加redis的依赖,如下: 配置 在application.yml文件中添加Redis相关的配置项,如下所示: 案例 1、字符串元素 2、List元…

    springboot 2023年3月26日
    121
  • Springboot 注解 @Primary

    作用 在注入依赖的过程中,当有多个候选者的时候,可以指定哪个候选者为主要的候选者。可以用在类上或者方法上面。通常定义bean常见的有2种方式:1、在类上标注@Component注解…

    springboot 2022年9月26日
    238
  • SpringBoot 单元测试

    简介 Spring Boot 2.2.0 版本开始引入 JUnit 5 作为单元测试默认库,在 Spring Boot 2.2.0 版本之前,spring-boot-starter…

    springboot 2023年4月2日
    242
  • SpringBoot 打包

    SpringBoot 项目部署到服务器常见的方式就是,打包成 jar 包,通过 nohup java -jar 命令去运行项目,这也是官方推荐的一种方式。 导入依赖 打包 设置打包…

    springboot 2023年4月5日
    148
  • SpringBoot 整合Memcached

    简介 Memcached 是一个高性能的分布式内存对象的key-value缓存系统,用于动态Web应用以减轻数据库负载,现在也有很多人将它作为内存式数据库在使用,memcached…

    springboot 2023年4月24日
    242
  • SpringBoot 整合Mybatis-Plus

    简介 MyBatis-Plus是一个MyBatis的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发,提高效率而生。 添加依赖 注意:添加Mybatis-Plus即可…

    springboot 2023年3月26日
    131
  • Springboot 注解 @Resource

    作用 和@Autowired注解类似,也是用来注入依赖对象的,spring容器会对bean中所有的字段、方法进行遍历,标注有@Resouce注解的,都会进行注入。@Autowire…

    springboot 2022年9月14日
    270
  • Springboot 注解 @ConfigurationProperties

    作用 @ConfigurationProperties注解主要作用就是将prefix属性指定的前缀配置项的值绑定到这个Bean上,默认情况下需要和@Component或者@Conf…

    springboot 2022年9月2日
    181