依赖注入及AOP简述(六)——字符串请求模式
来源:互联网 发布:淘宝cpu散片 编辑:程序博客网 时间:2024/05/21 09:31
2. 依赖注入对象的请求模式
前一节我们讨论了关于声明注入点的几种方法,这一节主要来介绍在注入点上如何定位到所需要的标识符的话题。基本上,我们可以用字符串为标识符来请求依赖对象、或者用全类名(FQCN)为标识符来请求依赖对象、或者用两者混合的模式。下面我们来依次介绍。
2.1. 字符串请求模式
顾名思义,字符串请求模式即依赖注入框架将一个依赖绑定到指定的字符串上,而后将其装入依赖注入容器。依赖者通过这个字符串,向容器请求所需要的依赖。Seam和Spring都是典型的基于字符串请求模式的框架。
在这样的模式中,容器中管理的依赖的标识符是通过字符串来定义的,例如我们刚才定义Bank和DepositBook依赖的时候,就是分别将其绑定到了“bank”和“depositBook”这两个字符串上。
@Name("bank") // 将BankICBC依赖绑定到"bank"
public class BankICBC implements Bank { // …… }
@Name("depositBook") // 将DepositBookICBC依赖绑定到"depositBook"
public class DepositBookICBC implements DepositBook { // …… }
之后对于依赖者类,只要在注入点上声明需要请求标识符字符串为“bank”或“depositBook”的依赖,容器就会自动将BankICBC和DepositBookICBC的实例返回给依赖者了。注意前面我们也提到了,Seam框架中在@In注入点缺省是被认为请求与成员变量名同名的依赖,因此下面两种请求依赖的写法是一样的:
@In // 请求标识符为"bank"的依赖对象
private Bank bank;
@In // 请求标识符为"depositBook "的依赖对象
private DepositBook depositBook;
@In("bank") // 请求标识符为"bank"的依赖对象
private Bank bank;
@In("depositBook") // 请求标识符为"depositBook "的依赖对象
private DepositBook depositBook;
尽管Seam和Spring都采用了纯字符串的标识符定义的模式,但这种模式下有一个很大的弱点:违反了“类型安全(type-safe)”原则,也就是说可能会误将一个本不是依赖者类所希望的依赖对象注入进来。试想这样的场景:假设开发者在开发Depositor类并定义其所需要的依赖的时候,误将“bank”写成了“bak”,而其他开发者又恰好向容器中注册了一个标识符为“bak”的依赖。
@In("bak") // 错误地请求了标识符为"bak"的依赖对象
private Bank bank;
@Name("bak ") // 其他开发者恰好向容器中注册了一个"bak"依赖
public class Bak { // …… }
此时Java编译器编译器是不会有任何错误信息提示的,因为@In是一个运行时注解,根据Java5的注解原理,运行时注解在编译时几乎就相当于一个注释行被编译器忽略掉了,只有到了运行时才会由解析它的代码段产生作用。因此无论是开发者定义成@In(“bak”)还是@In(“bakxxx”)等等,都不会对代码的编译造成任何影响。在这个例子中,虽然开发人员误将“bak”依赖请求进来,但会正常编译出应用程序,然后在运行这个应用程序的时候则会抛出ClassCastException的异常,这是就需要开发者花力气去排查错误了。
当然如果情况比较简单的话或许可以很快地排查掉这个bug,但是还有比这更可怕的事情:试想假设Bak类与Bank类是有继承关系的父子类,那么即使是在运行时也不会抛出ClassCastException的异常,因为依赖可以正确地被cast后set到注入点,这就有可能使得应用程序在被执行了很深之后才出现意想不到的bug,此时再去排查错误就会变得很困难了。
当然还有另外一种情况,就是如果容器中没有“bak”这个依赖的情况。此时声明注入点处的代码如果没有特殊限定,容器很可能将一个null对象设定到注入点,依然只会在运行时抛出NullPointerException异常。NPE异常或许是Java开发者最不愿意看到的异常了,因为它自描述性差,使得开发者经常很难定位错误所在。- 依赖注入及AOP简述(六)——字符串请求模式
- 依赖注入及AOP简述(七)——FQCN请求模式
- 依赖注入及AOP简述(八)——混合请求模式
- 依赖注入及AOP简述(三)——依赖注入的原理
- 依赖注入及AOP简述(四)——“好莱坞原则”和依赖注入框架简介
- 依赖注入及AOP简述(五)——依赖注入的方式
- 依赖注入及AOP简述(三)——依赖注入的原理
- 依赖注入及AOP简述(四)——“好莱坞原则”和依赖注入框架简介
- 依赖注入及AOP简述(十二)——依赖注入对象的行为增强(AOP)
- 依赖注入及AOP简述(十三)——AOP应用举例(完结)
- 依赖注入及AOP简述(一)——“依赖”的概念
- 依赖注入及AOP简述(一)——“依赖”的概念
- 依赖注入及AOP简述(二)——工厂和ServiceLocator
- 依赖注入及AOP简述(九)——单例和无状态Scope
- 依赖注入及AOP简述(十)——Web开发中常用Scope简介
- 依赖注入及AOP简述(十一)——生命周期管理
- 依赖注入及AOP简述(二)——工厂和ServiceLocator
- 依赖注入及AOP简述系列文章
- 3个超级有用的jQuery内容滚动插件和教程
- C# V3.5 OpenNETCF实现PC与CE设备的文件拷贝
- 《学习opencv》第五章课后习题1
- 文件mime类型
- 分布式系统漫谈一 —— Google三驾马车: GFS,mapreduce,Bigtable
- 依赖注入及AOP简述(六)——字符串请求模式
- js中this的总结
- js获取光标位置
- 第三讲:Android模拟器的使用
- 使用CSplitterWnd实现拆分窗口(多视图显示)
- 深入浅出PowerShell——部署SharePoint解决方案包
- 《学习opencv》第四章课后习题3
- 数据库集群的分类和各大商业数据库上的应用
- Android Matrix 学习