思考一:@Autowired. @Resoure @Inject 的区别是什么?
思考二:@Qualifier @Primary的区别?
下面实例讲解一下@Autowired. @Resoure @Inject 的区别是什么?
1
、如果容器中出现多个orderService
?怎么办呢?
//第一个beanId = orderService
@Service
public class OrderService{
}
//第二个bean Id = orderService2
@Configuration
public class MainConfig{
@Bean(“orderService2”)
public OrderService orderService(){
}
}
Bean id的命名规则:
-
如果没有自定义bean id的名称,加了@Service @Controller @Repository 注解的类在容器中的bean id默认为类名称,第一个字母小写;
-
加了@Bean注解 加载注册的Bean,默认的bean id为方法名;
1、@Autowire
依赖注入:
@Autowired
private OrderService orderService;
默认按类型去取,发现多个再按bean Id = orderService去取,所以取的是第一个;
1.1、@Autowire的require属性
如果容器中没有任何一个
orderService
,怎么办呢?
没有bean当然会报错,但是可以设置: @Autowire(require = false)
默认是require=true,如果没有就会报错;
2.2
、如果一定要使用
o
rderService2
呢?
将bean id指向
o
rderService2即可;
@Autowire
private OrderService orderService2;
2、@Qualifier和@Primary的加载优先级
2.1
、如果设置了
OrderService
orderService2
,但是还是想用
orderService
怎么办呢?
此时可以用@Qualifier来指定bean id 的名字即可;
@Qualifier(“orderService”)
@Autowire
private OrderService orderService2;
2.2、如果又加了@Primary控制优先级后,
bean又
如何加载呢?
//第一个beanId = orderService
@Service
public class OrderService{
}
//第二个bean Id = orderService2
@Configuration
public class MainConfig{
@Primary
@Bean(“orderService2”)
public OrderService orderService(){
}
}
结论:
如果既有@Qualifier和@Primary注解,此时则
根据
@Qualifier指定的
bean id
获取
orderService
,不受
@Primary
的影响,
@Qualifier优先级高于@Primary
;
2.3、那么
@Primary
的功能在哪里呢?
当我们去掉@Qualifier注解后
@Autowire
private OrderService orderService;
这里加载的都是@Primary注解的orderService2,无论你的@Autowire下的bean id name是什么,通过@Primary注解的bean的优先级高,首选使用;
这里主要为了验证@Qualifier和
@Primary
的加载顺序。
当对于
OrderService
在容器中存在多个,且
@Qualifier
和
@Primary
都存在的时候,会发生什么呢?
结论:也就是思考题2:@Qualify和@Primary的区别?
-
@Qualifier 根据 bean id 指定获取 orderService ,不受 @Primary 的影响
-
没有加@Qualify注解的变量,遵循@Primary的规则
3、@Resource(JSR250)
去掉@Qualifier和@Autowire
@Resource
private OrderService orderService;
此时它会根据bean id去加载,不会用到@Primary注解的bean;
结论:
@Resource不受@Primary注解的影响
4、问题与思考
问题1、
bean组件加载优先级;
除了@Order外,还有@Primary@Qualify。
问题2、
如果容器中存在两个id相同的bean,会加载哪个呢?
(1) 同时存在@Qualifier 和@Primary两个注解,则使用@Qualifier;
(2) 如果只存在@Primary,则遵循primary加载原则;注意@Primary对@Resource不起作用;
问题3、
如何指定装配组件id进行加载?
使用注解@Qualifier
问题4
、容器加载不存在的bean会有什么问题?
可以使用@Autowired(required = false),当bean不存在时不会报错;
5、小结
Spring利用依赖查找DL和依赖注入DI,完成对ioc容器中的各个组件的依赖关系赋值。
除了@Autowire,@Resource这两个注解外,还有 @Inject,它们都能装配bean:区别如下:
@Autowire
默认类型
|
1、属于spring的注解,不能脱离spring;org.springframework.beans.factory.annotation.Autowired
2、支持required = false; bean不存在就会报错;
3、支持@Primary功能;
4、支持 方法/参数/构造函数
特点:
|
@Resource
默认名称
|
1、默认按名称去加载注入,
不支持@Primary功能;
2、不能支持@Autowire(required = false)
3、属于java规范JSR250中的注解,JDK1.6支持的注解;javax.annotation.Resource
|
@Inject
|
1、支持Primary功能,主要用于非spring框架;
2、属于java规范中的注解;
缺点:
1、无任何属性,
不支持@Autowire(required=false),
2、不是spring的环境,需要引入第三方包javax.inject,引入外部的bean实例;
|
水滴石穿,积少成多。学习笔记,内容简单,用于复习,梳理巩固。