spring的注解, 用来做自动装配; 如果用于属性上:
类型
匹配, 类型匹配失败会用 name
匹配;
如果匹配到 多个
: 再用 @Qualifier("beanName")
的beanName来筛选, 看装配哪个bean;
如果一个都匹配不到, 而且声明了属性 required=false , 不调用不会报错; 调用就会 NoSuchBeanDefinitionException
;
不仅可以用在 属性
上, 也可以用到 方法
/ 构造器
/ 方法参数
上: (用在方法上和用在入参上意义是相同的)
如果使用在set方法上和构造方法上, 都有入参; 不论有没有@Autowired注解在方法上和参数上, 都会从IOC容器中去装配, 不会报错;
@Qualifier的作用如上; 用来在装配某个类型的bean时, 找到多个bean后用它的value作为name来区分;
@Primary
如果某个类型的bean在IOC容器中有多个可以匹配到; 在装配时又没有指定@Qualifier(value="beanName"); 此时, 就会首先筛选声明时标注了 @Primary的bean来装配!
@Resource默认先按照name来匹配, 如果 name
匹配不到, 再按照 类型
去匹配; 也可以和 @Qualifier 和 @Primary 一起使用;
name
匹配, 匹配不到采用 类型
; @Autowired首先按照 类型
匹配, 匹配到多个才会用 name
筛选; required
属性, 没有可选bean, 即使不调用, 也会报: NoSuchBeanDefinitionException
; 参数
和 构造方法
上; @Autowired可以(ElementType.PARAMETER, ElementType.CONSTRUCTOR)! name
和 类型
双备选, 一个找不到, 用另一个; Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.niewj.service.ProductService' available: expected single matching bean but found 2: productService,productService2
配置类: 这里有一个ProductService初始化: productService2
package com.niewj.config; import com.niewj.service.ProductService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan({"com.niewj.controller", "com.niewj.service"}) public class AutowiredTestConfig { // @Primary @Bean(name = "productService2") public ProductService product2(){ ProductService productService = new ProductService(); productService.setLabel("2"); return productService; } }
Service类: 这里也有一个ProductService注入springIOC: productService(默认名字类名首字母小写)
package com.niewj.service; import lombok.Data; import org.springframework.stereotype.Service; @Data @Service public class ProductService { private String label="1"; public void print(){ System.out.println("ProductService --> print"); } }
Controller类:
package com.niewj.controller; import com.niewj.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import javax.annotation.Resource; @Controller public class ProductController { // // 不指定 @Qualifier("productService2") 时, 在 productService2 处使用 @Primary也能首选 productService2 // // 指定 @Qualifier("productService2") // @Qualifier("productService3") // 如果没有指定 required=false, 匹配不到则会报告异常: NoSuchBeanDefinitionException // // @Autowired(required = false) // @Autowired // private ProductService productService; @Autowired private ProductService productService2; public void doPrint(){ System.out.println(productService2); } }
测试用例:
package com.niewj; import com.niewj.config.AutowiredTestConfig; import com.niewj.controller.ProductController; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import java.util.stream.Stream; /** * spring 自动装配 */ public class AutowiredTest { @Test public void testAutowired() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AutowiredTestConfig.class); // 打印spring容器中的 BeanDefinition Stream.of(ctx.getBeanDefinitionNames()).forEach(e-> System.out.println(e)); System.out.println("============================="); ProductController productController = ctx.getBean(ProductController.class); productController.doPrint(); ctx.close(); } }
output:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory autowiredTestConfig bookController productController testController subPacController bookService productService productService2 ============================= ProductService(label=2)
@Autowired/@Value/@Inject等注解都是用 AutowiredAnnotationBeanPostProcessor
类实现的~BeanPostProcessor;
同样的实现还有: Aware接口
@ApplicationContextAware 可以获取IOC容器上下文;
@ApplicationEventPublisherAware 获取事件发布器;
@EnvironmentAware 获取属性配置信息;
@EmbeddedValueResolverAware 内置字段的解析, 可以支持 ${}表达式, spEL #{}等;