@Autowired
spring的注解, 用来做主动拆卸; 如果用于属性上:
首先依照
类型
匹配, 类型匹配失败会用name
匹配;如果匹配到
多个
: 再用@Qualifier("beanName")
的beanName来筛选, 看拆卸哪个bean;如果一个都匹配不到, 而且申明了属性 required=false , 不调用不会报错; 调用就会
NoSuchBeanDefinitionException
;
不仅能够用在属性
上, 也能够用到办法
/结构器
/办法参数
上: (用在办法上和用在入参上意义是雷同的)
如果应用在set办法上和构造方法上, 都有入参; 不管有没有@Autowired注解在办法上和参数上, 都会从IOC容器中去拆卸, 不会报错;
@Qualifier
@Qualifier的作用如上; 用来在拆卸某个类型的bean时, 找到多个bean后用它的value作为name来辨别;
@Primary
如果某个类型的bean在IOC容器中有多个能够匹配到; 在拆卸时又没有指定@Qualifier(value=”beanName”); 此时, 就会首先筛选申明时标注了 @Primary的bean来拆卸!
@Resource
JSR250的注解, 属于java标准;
@Resource默认先依照name来匹配, 如果
name
匹配不到, 再依照类型
去匹配; 也能够和 @Qualifier 和 @Primary 一起应用;
@Resource和@Autowired比拟:
不同点
- @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类:
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 #{}等;
发表回复