spring的註解, 用來作自動裝配; 若是用於屬性上:java
首先按照類型
匹配, 類型匹配失敗會用name
匹配;若是匹配到
多個
: 再用@Qualifier("beanName")
的beanName來篩選, 看裝配哪一個bean;spring若是一個都匹配不到, 並且聲明瞭屬性 required=false , 不調用不會報錯; 調用就會
NoSuchBeanDefinitionException
;shell
不只能夠用在屬性
上, 也能夠用到方法
/構造器
/方法參數
上: (用在方法上和用在入參上意義是相同的)測試
若是使用在set方法上和構造方法上, 都有入參; 不論有沒有@Autowired註解在方法上和參數上, 都會從IOC容器中去裝配, 不會報錯;
@Qualifier的做用如上; 用來在裝配某個類型的bean時, 找到多個bean後用它的value做爲name來區分;
@Primaryui
若是某個類型的bean在IOC容器中有多個能夠匹配到; 在裝配時又沒有指定@Qualifier(value="beanName"); 此時, 就會首先篩選聲明時標註了 @Primary的bean來裝配!
JSR250的註解, 屬於java規範;@Resource默認先按照name來匹配, 若是
name
匹配不到, 再按照類型
去匹配; 也能夠和 @Qualifier 和 @Primary 一塊兒使用;code
- @Resource首先按照
name
匹配, 匹配不到採用類型
; @Autowired首先按照類型
匹配, 匹配到多個纔會用name
篩選;- @Resource是JSR250的註解, 是java規範定義的; @Autowired是spring定義的註解;
- @Resource沒有@Autowired(required=false)裏的
required
屬性, 沒有可選bean, 即便不調用, 也會報:NoSuchBeanDefinitionException
;- @Resource不能使用到
參數
和構造方法
上; @Autowired能夠(ElementType.PARAMETER, ElementType.CONSTRUCTOR)!
- 都有備選機制: 即
name
和類型
雙備選, 一個找不到, 用另外一個;- 當匹配到多個時, 均可以配合使用@Qualifier 和 @Primary來區分;
- 當匹配到多個時, 匹配到多個, 也沒有@Qualifier 和 @Primary註解區分, 兩個註解都會報異常:
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類:get
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); } }
測試用例:it
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 #{}等;