自动装配:Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值。
1、@Autowired 自动注入(Spring定义的)
①、默认按照组件类型去容器中找对应的组件进行注入:annotationConfigApplicationContext.getBean(BookDao.class),如果找到就赋值,找不到默认抛出异常。
②、如果找到多个同类型的组件,在根据属性名去容器中找对应的组件:annotationConfigApplicationContext.getBean("bookDao")如果找到就赋值,找不到默认抛出异常。
③、可以使用@Qualifier注解指定需要装配组件的id。
④、自动装配默认一定要将属性赋值好,如果找不到对应的组件,则会报错。但Spring允许我们使用@Autowired(required=false)来指定,如果找不到组件,则返回null,而不是直接异常。
⑤、Spring还提供了一个注解@Primary,来指定首选的Bean。也就是说多个同类型的Bean优先加载@Primary标注的组件。
⑥、@Primary和@Qualifier("bookDao")都指定的情况下,@Qualifier优先级更高。
⑦、@Autowired除了可以标注在属性上,还可以标注到构造器,参数和方法上。
1)标注在方法上,其中@Bean标注的方法创建对象的时候,如果方法里面有参数,参数也是从容器中获取,默认是可以不加@Autowired注解的。
2)标注在构造器上,如果组件只有一个有参构造器,@Autowired注解也可以省略,参数位置的组件仍然从容器中获取。
3)标注在参数位置
2、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[Java规范的注解]
①、@Resource(JSR250):
1)可以像@Autowired一样实现Bean自动装配的功能。默认按照属性的名称来装配。
2)但是不支持@Primary和@Qualifier以及@Autowired(required=false)。
3)可以通过@Resource(name="bookDao2")来指定加载那个Bean。
②、@Inject(JSR330)
1)该注解想要使用的话,需要在pom文件中导入依赖:javax.inject。
2)和@Autowired的功能一样,@Primary和@Qualifier注解都可以生效
3)但是Inject没有@Autowired(required=false)功能。也就是使用Inject注入的组件不能找不到,找不到就直接报错。
备注:Spring完成是通过后置器:AutowiredAnnotationBeanPostProcessor来完成自动装配功能的。
3、自定义组件注入Spring容器底层的一些组件(ApplicationContext,BeanFactory)
Spring提供了各种各样的Aware接口,自定义组件可以通过实现XXXAware接口来实现底层组件的自动装配。(在创建对象的时候,就会调用接口规定的方法,注入相关的组件)例如:
IOC容器获取:XXXAware
字符串解析器:EmbeddedValueResolverAware
备注:XXXAware接口方式注入Spring底层组件方式是通过相应的XXXAwareProcessor后置器实现的。
4、@Profile(Spring为我们提供的可以根据当前环境动态的激活和切换一些列组件的功能)
①、指定组件在哪个环境下才能被注册到容器中,不指定的情况下,任何环境都可以加载。
②、加了环境标识的bean,只有在这个环境被集火的时候,才能注册到容器中,默认是default。
③、@Profile也可以写在配置类上,标识只有在指定环境的时候,整个配置类里面所有配置才能生效。
④、环境的指定方式如下:
1)通过命令行动态参数,在虚拟机参数位置设置:-Dspring.profiles.active=test
2)使用代码的方式激活某种环境如下:
//使用无参构造器创建一个IOC容器
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext();
//设置需要激活的环境
annotationConfigApplicationContext.getEnvironment().setActiveProfiles("dev");
//注册主配置类
annotationConfigApplicationContext.register(MainConfigOfProfile.class);
//启动刷新容器
annotationConfigApplicationContext.refresh();