背景
实际项目中,我们都会用到Spring容器去存放我们的Bean对象,获取Bean对象时我们常用的@Autowired注解去进行导入,那么该方式有什么缺点?那么获取Bean还有哪些方式?这些方式都有哪些区别呢?啊这些都不重要,重要的是当成为面试题该怎么聊?那么我们挨个进行分析。
@Autowired
说到@Autowired,最常用的一个注解了,Controller层导入Service,Service层导入Mapper,Service层也可以导入通过外观模式封装的公用代码,导入第三方Api Service。这些操作都可以通过@Autowired来进行,那么其执行方式是去Spring IOC容器中寻找对应类型的Bean,如以下代码则代表在容器中寻找Order的Bean对象
@Autowired
private Order order;
那么如果Spring容器中有该Order对象时会被其获取,也就是
那么我们知道Java是支持继承的,如果这个时候有OrderService接口,同时有两个Order对象实现了其,那么我们去注入OrderService时,会出现什么情况呢?
如图,那么实际上是会抛出异常的,Autowired只会去自动寻找一个匹配项,如果匹配出多个的情况下,会跑出找到了一个以上的Bean的异常,无法选择对应的Bean,那么如何去解决这个问题呢?这个时候我们只需要在Order01的类上加上@Primary注解即可。
@Primary:表示设置该Bean为主要的Bean,注入时会优先加载该Bean。
@Qualifier("order02")通过与@Autowired联合使用该注解,亦可指定注入某个Bean
我们进行一个小的总结:
1.@Autowired注入Bean时,如果找到0个Bean,抛出异常,参数required设置为false时不会抛出,默认为true。
2.@Autowired注入Bean时,如果找到1个Bean,成功装配。
3.@Autowired注入Bean时,如果找到多个Bean,抛出找到1个以上Bean的异常,启动失败。
那么上文我们说到。长沙的雨下得很大,嘀嗒嘀嗒,天黑的混混沉沉....等等,跑题了
@Resources
在JDK中,有这么一个注解也是可以去获取Spring容器中的Bean的,同理,处理@Autowired遇到的问题时,使用@Primary注解与@Qualifier同样可以解决,当然该注解亦可以通过以下形式在多个Bean对象时注入该对象。
@Resource(name = "order02")
ApplicationContext上下文
我们不难在项目中看到SpringUtil类,通过下例代码可以获取上下文,从中能够获取到对应的Bean对象。
SpringUtil.getApplicationContext();
构造函数注入
构造函数注入是Spring官方推荐的注入方式,但是该方式默认没有解决Bean循环依赖的BUG,注入格式如下。该形式的注入甚至可以忽略掉@Autowired注解即可注入。
private Order order;
public Service(Order order) {
this.order = order;
}
总结
以上,即项目中常用到的一些Bean注入方式,当然,方式远远不止以上四种,但是大体都是根据SpringContext上下文去进行的,大同小异。关于SpringBean获取的那些事儿我们分析到此。