Spring注解-自动装配(三)

@Autowired, @Qualifier, @Primary

  • 自动装配
  1. 就是Spring利用依赖注入(DI), 完成对IOC容器中各个组件的依赖关系赋值.
  • @Autowired注解
  1. 默认优先按照类型去容器中找对应的组件.
  2. 如果找到了多个相同类型的组件, 再将属性名作为组件id去容器中查找.
  3. 自动装配默认一定要将属性赋值好. 否则就会报错.
    • 如果想找到就找到, 没找到就拉倒, 那需要设置其required属性
      @Autowired(required = false)
      private BookDAO bookDAO2;
  • @Qualifier注解
  1. 在@Autowired上加@Qualifier注解, 指定要装配的组件.
        @Qualifier("bookDAO")
        @Autowired(required = false)
        private BookDAO bookDAO2;
  • @Primary注解
  1. 利用该注解, 让Spring进行自动装配时, 默认使用首选的bean. 要谁做首选就给谁标注@Primary.
    @Configuration
    @ComponentScan({ "test" })
    public class MainConfigAutoWired {
    
        @Primary
        @Bean("bookDAO2")
        public BookDAO bookDAO() {
    
            BookDAO bookDAO = new BookDAO();
            bookDAO.setLable("2");
    
            return bookDAO;
        }
    }
    
    //这种情况下, 若未用@Qualifier明确指定, 则装配BookDAO类型的优先装载它.
  2. 区别: @Qualifier是明确指定要装配哪个, @Primary是指定首选bean.

@Resource, @Inject

  1. 除了@Autowired注解, Spring还支持@Resource(JSR250)和@Inject(JSR330) [java规范的注解]
  • @Resource注解
  1. 它可以实现自动装配功能, 但该注解默认按照组件名称进行装配的. 
    • name属性指定要装配的组件id.
      @Service
      public class BookService {
      
          @Resource(name = "bookDAO")
          private BookDAO bookDAO2;
      
              //...
      }
  2. 该注解是Java规范的注解, 不是Spring的注解, 所以不支持@Primary, @Qualifier, 和required属性.
  • @Inject注解
  1. 使用该注解需要导入依赖
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>
  2. 也是优先按照类型装配. 但功能没有Autowired强大.

自动装配-方法/构造器/参数

  1. @Autowired: 能在构造器, 参数, 方法, 属性处标注.
  • 把@Autowired标在方法上.
  1. 标注在方法上, Spring容器创建当前对象, 就会调用方法完成赋值.
  2. 方法中使用的参数, 自定义类型的值从ioc容器中获取
    • 一般会把@Autowired加在set方法上
      public class Boss {
      
          private Car car;
      
          public Car getCar() {
              return car;
          }
      
          @Autowired
          public void setCar(Car car) {
              this.car = car;
          }
      
          @Override
          public String toString() {
              return "Boss [car=" + car + "]";
          }
      
      }
  3. 注意: @Bean标注的方法创建对象的时候, 方法参数的值会从容器中获取.
  • 把@Autowired标在构造器上
  1. 默认加在ioc容器中的组件, 容器启动会调用无参构造器创建对象, 再进行初始化赋值等操作.
  2. 标在构造器上, 构造器所需组件, 也是在ioc容器中查找的
    @Component
    public class Boss {
    
        private Car car;
    
        @Autowired
        public Boss(Car car) {
            super();
            this.car = car;
            System.out.println("Boss..有参构造器");
        }
    
        public Car getCar() {
            return car;
        }
    
        public void setCar(Car car) {
            this.car = car;
        }
    
        @Override
        public String toString() {
            return "Boss [car=" + car + "]";
        }
    
    }
  3. 若组件只有一个有参构造器, 这个有参构造器的@Autowired可以省略, 参数位置的组件还是可以从容器中自动获取.
  • 把@Autowired标在参数位置.
  1. 也是从容器中获取参数组件的值.
    public Boss(@Autowired Car car) {
            super();
            this.car = car;
            System.out.println("Boss..有参构造器");
        }

Profile

  • Profile
  1. 这是Spring为我们提供的可以根据当前环境, 动态激活和切换一系列组件的功能.
  2. 比如: 有开发环境, 测试环境, 生产环境, 以数据源为例.
    • 生产时要用A数据库, 开发时用B数据库.
    • 利用@profile解决上述问题.
  • @Profile
  1. 指定组件在哪个环境的情况下才能被注册到容器中. 不指定, 则任何环境下都能加载这个组件.
    • @Configuration
      public class MainConfigOfProfile {
      
          @Profile("test")
          @Bean
          public Yellow yellow() {
      
              return new Yellow();
          }
      
          @Profile("dev")
          @Bean
          public Car car() {
      
              return new Car();
          }
      
          @Profile("prod")
          @Bean
          public Cat cat() {
      
              return new Cat();
          }
      }
    • 当@Profile写在配置类上时, 只有是指定的环境的时候, 整个配置类里面所有的配置才能生效.
  2. 加了环境标识的bean, 只有这个环境被激活的时候才能注册到容器中.
    • 默认是default环境
  3. 如何加环境标识?
    • 使用命令行动态参数: -Dspring.profiles.active=test
      • 右键 Run as Configurations...
    • 使用代码方式激活某种环境
          @Test
          public void test04() {
              
              //1. 创建一个applicationContext
              AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
              //2. 设置我们要激活的环境
              ac.getEnvironment().setActiveProfiles("test", "dev");
              //3.注册主配置类
              ac.register(MainConfigOfProfile.class);
              //4.启动刷新容器
              ac.refresh();
              
              Object bean = ac.getBean("yellow");
              System.out.println(bean);
              
              ac.close();
          }
原文地址:https://www.cnblogs.com/binwenhome/p/13073256.html