Files
rikako-note/spring/Spring core/Spring Core IOC.md
2022-06-28 22:32:52 +08:00

6.9 KiB
Raw Blame History

Spring Core IOC

  • IOC容器和bean简介

    • IOC简介
      • IOC控制反转也被称之为依赖注入DI对象通过构造函数参数、工厂方法参数、或者在构造后通过setter来设置属性来定义依赖。在对象被创建时IOC容器会将依赖注入到bean对象中
    • IOC容器
      • IOC容器接口
        • BeanFactoryBeanFactory是一个接口提供了高级配置功能来管理任何类型的对象
        • ApplicationContextApplicationContext是BeanFactory的一个子接口在BeanFactory的基础上其添加了一些更为特殊的特性。
      • IOC容器职责
        • IOC容器负责来初始化、配置、组装bean对象
  • 基于注解的Spring容器配置

    • @Required
      • @Required应用于bean对象属性的setter方法表示该属性在配置时必须被填充通过依赖注入或是用xml定义bean时显式指定值
      • 该注解当前已经被弃用
    • @Autowired
      • 通过在构造函数上标明@Autowired来对方法参数进行注入
      • 当在构造函数上标记@Autowired时如果当前类中只有一个构造函数那么@Autowired注解可以被省略如果当前类有多个构造函数那么应该在某个构造函数上指明@Autowired注解
      @Component
      class Shiromiya {
          private JdbcTemplate jdbcTemplate;
      
          @Autowired
          public Shiromiya(JdbcTemplate jdbcTemplate) {
              this.jdbcTemplate=jdbcTemplate;
          }
      }
      
      • 同样可以在setter上应用@Component
      @Component
      class Shiromiya {
          private JdbcTemplate jdbcTemplate;
      
          @Autowired
          public setJdbcTemplate(JdbcTemplate jdbcTemplate) {
              this.jdbcTemplate=jdbcTemplate;
          }
      }
      
      • 将@Autowired应用于字段
      @Component
      class Shiromiya {
          @Autowired
          private JdbcTemplate jdbcTemplate;
      }
      
      • 通过@Autowired获取相同类型的所有bean对象
      @Component
      class Shiromiya {
          private String[] waifus;
          /*
          * 这里同样也支持Collections类型
          * 例如 List<String>
          */ 
      
          @Autowired
          public Shiromiya(String[] waifus) {
              this.waifus=waifus;
          }
      }
      
      // 同样可以通过Map类型来获取所有相同类型bean对象的name和value
      // key对应bean对象的name
      // value对应该bean对象的值
      @Component
      class Shiromiya {
          private Map<String,String> waifus;
      
          @Autowired
          public void setWaifus(Map<String,String> waifus) {
              this.waifus=waifus;
          }
      }
      
      • 在@Autowired标记在构造函数上时即使required为true在参数为多bean类型时即使没有匹配的bean该属性会赋值为{}(空集合)而不是抛出异常
      • @Autowired作用与构造函数的规则
        • 当required属性为其默认值true时在bean类型中只有一个构造函数可以用@Autowired标注
        • 如果bean类型中有多个构造函数标注了@Autowired注解那么那么他们都必须将required属性设置为false并且所有标注了@Autowired属性的构造函数都会被视为依赖注入的候选构造函数
          • 如果有多个候选的构造函数那么在IOC容器中可以满足的匹配bean最多的构造函数将会被选中
          • 如果没有候选函数被选中,那么其会采用默认构造函数,如无默认构造函数,则抛出异常
        • 如果bean有多个构造函数并且所有构造函数都没有标明@Autowired注解那么会采用默认构造函数如果默认构造函数不存在抛出异常
        • 如果bean类型只有一个构造函数那么该构造函数会被用来进行依赖注入即使该构造函数没有标注@Autowired注解
      • 除了使用@Autowired的required属性还可以使用@Nullable注解来标注可为空
      @Component
      public class Shiromiya {
          @Autowired
          @Nullable
          private int num;
      }
      
    • @Primary
      • @Autowired注解是通过类型注入如果相同类型存在多个bean时可以通过@Primary注解来表明一个primary bean
      @Configuration
      public class BeanConfiguration {
          @Bean
          @Primary
          public String name_1() {
              return "kazusa";
          }
      
          @Bean
          public String name_2() {
              return "ogiso";
          }
      }
      /*
       * 此时,若通过@Autowired注入String类型“kazusa”将会是默认值
       */ 
      
    • @Qualifier
      • 可以通过@Qualifier来指定bean的name导入特定bean并且可以为bean指定默认的qualifier
      @Component
      public class Shiromiya {
          @Autowired
          @Qualifier("name_2")
          private String n_2;
      
          private String n_1;
      
          @Autowired
          public Shiromiya(@Qualifier("name_1") String n) {
              this.n_1=n;
          }
      }
      
      • bean对象的qualifier并不需要唯一可以为不同的bean对象赋值相同的qualifier并且在注入bean集合的时候根据qualifier过滤
      @Configuration
      @Qualifier("config")
      class BeanConfiguration {
          @Bean
          @Qualifier("name")
          public String name_1() {
              return "kazusa";
          }
      
          @Bean
          @Qualifier("name")
          public String name_2() {
              return "ogiso";
          }
      
          @Bean
          @Qualifier("not-name")
          public String not_name_1() {
              return "fuck";
          }
      }
      
      @Component
      public class Person {
          /* 此nameList属性会注入qualifier为name的所有bean
           * 在此处为"kazusa"和"ogiso" 
           */ 
          @Autowired
          @Qualifier("name")
          Map<String,String> nameList;
      
          @Autowired
          @Qualifier("config")
          BeanConfiguration conf;
      
          @Override
          public String toString() {
              return "Person{" +
                      "nameList=" + nameList +
                      ", conf=" + conf +
                      '}';
          }
      }
      
      • 作为一种回退机制当bean的qualifier未被定义时bean的name属性将会被作为其qualifierautowired时会根据@Qualifier注解中指定的值匹配具有相同name的bean对象
      • 若想根据bean的name进行匹配无需@Qualifier注解只需要将注入点的name(filed的变量名标注为@Autowired函数的形参名)和bean的name进行比较如果相同则匹配成功否则匹配失败
      • @Autowired同样支持自身引用的注入但是自身引用的注入只能作为一种fallback机制。如果当前IOC容器中存在其他的同类型对象那么其他对象会被优先注入对象自己并不会参与候选的对象注入。但是如果IOC中并不存在其他同类型对象那么自身对象将会被作为引用注入。