Bean 注解(Annotation)配置(3)- 依赖注入配置

注解方式配置Bean之间的依赖关系,可通过注解:@Autowired

Spring扫描所有带有@Component注解的类,将其注册为bean,然后Spring找到带有@Autowired注解的变量,把所依赖的Bean注入。

使用@Autowired注解注入依赖项有3种方法:

  • 构造函数注入
  • Setter注入
  • 字段注入

确保所依赖的类已经配置成Bean,否则不能注入。

我们有下面几个类:

Database.java


package com.qikegu.demo; import org.springframework.stereotype.Component; @Component public class Database implements Service { @Override public String name() { return "数据库名称:MySQL"; } @Override public void run() { System.out.println("数据库正在运行"); } @Override public void stop() { System.out.println("数据库已经停止"); } }

Logger.java

package com.qikegu.demo;

import org.springframework.stereotype.Component;

@Component
public class Logger implements Service {
  @Override
  public String name() {
    return "Logger X";
  }

  @Override
  public void run() {
    System.out.println("Loggery已经准备好");
  }

  @Override
  public void stop() {
    System.out.println("Logger已经停止");
  }
}

Mail.java

package com.qikegu.demo;

import org.springframework.stereotype.Component;

@Component
public class Mail implements Service {
  @Override
  public String name() {
    return "邮件收发";
  }

  @Override
  public void run() {
    System.out.println("邮件收发正在运行");
  }

  @Override
  public void stop() {
    System.out.println("邮件收发已经停止");
  }
}

1. 构造方法注入

使用@Autowired注解将依赖项注入类的构造方法。

App.java

package com.qikegu.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class App {

  private Service mainService;
  private Service[] services;

  public App(){
  }

  /* 
  // 构造方法注入
  @Autowired
  public App(@Qualifier("logger") Service main){
    this.setMainService(main);
  } 
  */

  // 构造方法注入
  @Autowired
  public App(Service[] services){
    this.setServices(services);
  }

  public Service getMainService() {
    return mainService;
  }

  public void setMainService(Service mainService) {
    this.mainService = mainService;
  }

  public Service[] getServices() {
    return services;
  }

  public void setServices(Service[] services) {
    this.services = services;
  }
}

注意:只能有一个构造方法用于自动装配。

  • 问题1: 可以看到构造方法的参数类型Service是一个接口,它有几个实现类,那么这里将注入哪个实现类的实例呢?

如果只有一个实现类,默认情况下将注入这个类。

如果有多个实现类,需要使用@Qualifier("bean_id")注解显式指定。如果没有指定,Spring容器将根据变量名匹配一个实现类,如果找不到匹配,抛出异常。

对于public App(Service[] services) Service数组:Spring将注入所有实现类的实例。

  • 问题2: Spring容器以何种方式匹配Bean?

默认情况下是通过数据类型(byType),当使用@Qualifier注解时,是通过名称(byName)。

2. Setter方法注入

调用带有@Autowired注解的setter方法注入依赖项。

App.java

package com.qikegu.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class App {

  private Service mainService;
  private Service[] services;

  public App(){
  }

  public Service getMainService() {
    return mainService;
  }

  // Setter方法注入
  @Autowired
  @Qualifier("logger")
  public void setMainService(Service mainService) {
    this.mainService = mainService;
  }

  public Service[] getServices() {
    return services;
  }

  @Autowired 
  public void setServices(Service[] services) {
    this.services = services;
  }
}

其实任何带有@Autowired注解的方法,都可以注入依赖项,而不仅限于Setter方法。

// Setter方法注入
@Autowired
@Qualifier("logger")
public void anyMethod(Service mainService) {
  this.mainService = mainService;
}

3. 字段注入

通过在对象字段上使用@Autowired注解注入依赖项。

App.java

package com.qikegu.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class App {

  // 字段注入 
  @Autowired
  @Qualifier("logger") 
  private Service mainService;

  // 字段注入 
  @Autowired
  private Service[] services;

  public App(){
  }

  public Service getMainService() {
    return mainService;
  }

  public Service[] getServices() {
    return services;
  }
}
  • 问题:前面提到这几种依赖注入类型,哪种比较好?

各有优点,看自己偏好,选择一个在整个项目中保持一致

通过注解注入值

使用构造方法、setter方法和字段除了可以注入依赖项,还可以注入值。

App.java

package com.qikegu.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class App {

  // 使用@Value注解注入值
  @Value("1024")
  private int id;

  public App(){
  }

  // 使用@Value注解注入值
  public App(@Value("1024") int id){
    this.id = id;
  }

  public int getId() {
    return id;
  }

  // 使用@Value注解注入值
  @Value("1024")
  public void setId(int id) {
    this.id = id;
  }
}


浙ICP备17015664号 浙公网安备 33011002012336号 联系我们 网站地图  
@2019 qikegu.com 版权所有,禁止转载