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



    Spring 系列教程


    注解方式配置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;
      }
    }
    
  • 相关阅读:
    1114 Family Property (25 分)(并查集)
    【专题复习4:Dijkstra】1003、1018、1030、1072、1087、1111
    1133 Splitting A Linked List (25 分)(链表)
    【专题复习5:并查集】1107、1114、1118
    Java Window 下安装 java
    OpenShift4 节点TimeZone修改
    PHP魔术方法
    .NET中的HashSet
    格式化字符串
    Jetpack Compose
  • 原文地址:https://www.cnblogs.com/jinbuqi/p/10983456.html
Copyright © 2020-2023  润新知