@Autowired, @Qualifier, @Primary
- 自动装配
- 就是Spring利用依赖注入(DI), 完成对IOC容器中各个组件的依赖关系赋值.
- @Autowired注解
- 默认优先按照类型去容器中找对应的组件.
- 如果找到了多个相同类型的组件, 再将属性名作为组件id去容器中查找.
- 自动装配默认一定要将属性赋值好. 否则就会报错.
- 如果想找到就找到, 没找到就拉倒, 那需要设置其required属性
@Autowired(required = false) private BookDAO bookDAO2;
- 如果想找到就找到, 没找到就拉倒, 那需要设置其required属性
- @Qualifier注解
- 在@Autowired上加@Qualifier注解, 指定要装配的组件.
@Qualifier("bookDAO") @Autowired(required = false) private BookDAO bookDAO2;
- @Primary注解
- 利用该注解, 让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类型的优先装载它.
- 区别: @Qualifier是明确指定要装配哪个, @Primary是指定首选bean.
@Resource, @Inject
- 除了@Autowired注解, Spring还支持@Resource(JSR250)和@Inject(JSR330) [java规范的注解]
- @Resource注解
- 它可以实现自动装配功能, 但该注解默认按照组件名称进行装配的.
- name属性指定要装配的组件id.
@Service public class BookService { @Resource(name = "bookDAO") private BookDAO bookDAO2; //... }
- name属性指定要装配的组件id.
- 该注解是Java规范的注解, 不是Spring的注解, 所以不支持@Primary, @Qualifier, 和required属性.
- @Inject注解
- 使用该注解需要导入依赖
<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
- 也是优先按照类型装配. 但功能没有Autowired强大.
自动装配-方法/构造器/参数
- @Autowired: 能在构造器, 参数, 方法, 属性处标注.
- 把@Autowired标在方法上.
- 标注在方法上, Spring容器创建当前对象, 就会调用方法完成赋值.
- 方法中使用的参数, 自定义类型的值从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 + "]"; } }
- 一般会把@Autowired加在set方法上
- 注意: @Bean标注的方法创建对象的时候, 方法参数的值会从容器中获取.
- 把@Autowired标在构造器上
- 默认加在ioc容器中的组件, 容器启动会调用无参构造器创建对象, 再进行初始化赋值等操作.
- 标在构造器上, 构造器所需组件, 也是在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 + "]"; } }
- 若组件只有一个有参构造器, 这个有参构造器的@Autowired可以省略, 参数位置的组件还是可以从容器中自动获取.
- 把@Autowired标在参数位置.
- 也是从容器中获取参数组件的值.
public Boss(@Autowired Car car) { super(); this.car = car; System.out.println("Boss..有参构造器"); }
Profile
- Profile
- 这是Spring为我们提供的可以根据当前环境, 动态激活和切换一系列组件的功能.
- 比如: 有开发环境, 测试环境, 生产环境, 以数据源为例.
- 生产时要用A数据库, 开发时用B数据库.
- 利用@profile解决上述问题.
- @Profile
- 指定组件在哪个环境的情况下才能被注册到容器中. 不指定, 则任何环境下都能加载这个组件.
-
@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写在配置类上时, 只有是指定的环境的时候, 整个配置类里面所有的配置才能生效.
-
- 加了环境标识的bean, 只有这个环境被激活的时候才能注册到容器中.
- 默认是default环境
- 如何加环境标识?
- 使用命令行动态参数: -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(); }
- 使用命令行动态参数: -Dspring.profiles.active=test