依赖注入及AOP简述(六)——字符串请求模式 .

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开发者最不愿意看到的异常了,因为它自描述性差,使得开发者经常很难定位错误所在。

时间: 2025-01-16 23:32:52

依赖注入及AOP简述(六)——字符串请求模式 .的相关文章

依赖注入及AOP简述(七)——FQCN请求模式

2.2.    FQCN请求模式 为了弥补纯字符串请求模式中的类型安全问题,全类名(FQCN)请求模式就应运而生了.其思想便是,在向容器请求依赖对象的时候,不是通过字符串的标识符.而是通过被请求的依赖的全类名来定位依赖.这样如果开发者误将全类名标识符写错的话,在编译时立即会提醒“类不存在”.并且,如果使用Eclipse等IDE开发工具的话,用其提供的自动完整代码的功能就会轻松地将依赖的全类名标识符定义到代码中. 在第一章的“3.3 依赖注入框架简介”一节中我们提到了Google Guice框架是

依赖注入及AOP简述(八)——混合请求模式 .

2.3.    混合请求模式 上一节讲到了FQCN(全类名)请求模式会带来依赖定义的柔软性较差的问题,因此字符串和全类名混合的模式又应运而生了.比如刚才的Spring中的API方式声明注入点的例子就可以改为使用下面的API: // Spring的字符串+全类名注入的API BeanFactory injector = new FileSystemApplicationContext("depositConfiguration.xml") this.bank = (Bank) injec

依赖注入及AOP简述(三)——依赖注入的原理

3.     “依赖注入”登场 于是诸多优秀的IT工程师开始想出了更加轻量便利.更加具有可测试性和可维护性的设计模式——IoC模式.IoC,即Inversion of Control的缩写,中文里被称作“控制反转”.至于为什么会有这么一个看似古怪的名字,我们稍后会做解释.2004年著名软件工程学者和工程师Martin Fowler在其论文<Inversion ofControl Containers and the Dependency Injection pattern>中将IoC更名为De

依赖注入及AOP简述(五)——依赖注入的方式 .

二.依赖注入的应用模式 前面我们了解了依赖注入的基本概念,也对一些依赖注入框架进行了简单的介绍,这一章我们主要来讨论作为开发者如何利用依赖注入框架来实现依赖注入的设计思想. 1.     依赖注入的方式 前面我们提到,所谓“依赖”,最简单地去解释就是一个Java类里的成员变量.我们都知道,给一个类中的私有成员变量赋值的方法通常有:通过Constructor构造方法.通过Setter方法.通过反射机制将私有变量的可见性设为true这三种方法.同样道理,依赖注入框架也是利用这三种方式来完成依赖对象的

依赖注入及AOP简述(十二)——依赖注入对象的行为增强(AOP) .

四.依赖注入对象的行为增强(AOP) 前面讲到,依赖注入框架的最鲜明的特点就是能够提供受容器管理的依赖对象,并且可以对对象提供行为增强(AOP)功能,所以这一章我们来讨论有关AOP的话题. 1.     对依赖对象进行行为增强 所谓AOP,就是Aspect Oriented Programming(面向方面的编程),核心思想是把一个“方面”独立出来,从而实现组件间的松耦合.也许有些晦涩难懂,所以我们还是看个简单的例子. 在我们的银行依赖中,假设有个需求,即在每一笔取款业务的前后都要输出日志信息.

依赖注入及AOP简述(十三)——AOP应用举例(完结) .

2.     AOP应用举例 在一般的应用程序开发中,有一些典型的AOP应用,使得开发者可以专注于业务逻辑本身,而不是与之完全无关的一些“方面”. l        首先就是关于前面介绍过的日志输出类的功能,当然前面的例子非常简单,实际上要输出的日志信息中往往有很多的可变参数,这时就需要从被拦截对象的上下文中取出相应的信息进行行为的增强. l        最常用的AOP应用就是关于DB事务的管理了.业务处理成功则向DB提交事务,反之则回滚事务——这是每一个开发者都会写过的代码.但是实际上这种事

依赖注入及AOP简述(九)——单例和无状态Scope .

三.依赖注入对象的Scope及其生命周期 在前面的章节我们讲到,依赖注入容器之所以能够区别于以往的ServiceLocator等容器,是在于其不但能够自动构建多层次的.完整的依赖关系图,并且可以管理依赖对象的Scope和对其进行行为增强.有关行为增强的话题我们会在下一章介绍,这里我们先来看看有关依赖对象的Scope及其生命周期管理的话题. 1.     依赖注入对象的Scope Scope,即作用域,是指面向对象开发中所设计的某一类对象的生存期间.我们先从普通Java程序开发中最常用的单例和无状

依赖注入及AOP简述(四)——“好莱坞原则”和依赖注入框架简介 .

3.2.    “好莱坞原则” 看了前面关于依赖注入概念的描述,我们来提炼出依赖注入的核心思想.如果说传统的组件间耦合方式,例如new.工厂模式等,是一种由开发者主动去构建依赖对象的话,那么依赖注入模式则是其反向的,即被动地等待别人做好一个依赖对象提供给我. 在美国好莱坞众多电影工厂在寻找演员的时候通常奉行着这么一个原则:不要找我,需要的时候我去找你(“Don’tcall us; we’ll call you!”),把相同的思路运用到我们的软件工程里通常也被称作“好莱坞原则”(Hollywood

依赖注入及AOP简述(十一)——生命周期管理 .

2.     生命周期管理 各种依赖注入框架提供了替开发者管理各种Scope的便利功能,随之而来的就必然是被管理的依赖对象的生命周期管理的问题.所谓生命周期管理,就是一个对象在它所属的Scope中从被容器创建开始.到被提供给依赖者.再到最后的消亡这一整个过程中,依赖注入框架提供了一系列的回调方法的接口,使框架自身以及开发者都可以利用这些接口对各个生存时点的依赖对象做一些操作和管理等. 例如依赖注入容器在创建一个依赖对象的时候,远不是new一个对象那么简单,而是一个极其复杂地Wrap这个对象的过程