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简述(六)——字符串请求模式 .的更多相关文章

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

    2.2.    FQCN请求模式 为了弥补纯字符串请求模式中的类型安全问题,全类名(FQCN)请求模式就应运而生了.其思想便是,在向容器请求依赖对象的时候,不是通过字符串的标识符.而是通过被请求的依赖 ...

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

    2.3.    混合请求模式 上一节讲到了FQCN(全类名)请求模式会带来依赖定义的柔软性较差的问题,因此字符串和全类名混合的模式又应运而生了.比如刚才的Spring中的API方式声明注入点的例子就可 ...

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

    3.     “依赖注入”登场 于是诸多优秀的IT工程师开始想出了更加轻量便利.更加具有可测试性和可维护性的设计模式——IoC模式.IoC,即Inversion of Control的缩写,中文里被称 ...

  4. 依赖注入及AOP简述(二)——工厂和ServiceLocator .

    2.2.    工厂模式 基于手工构建组件的诸多弱点,1995年“大师4人组”(GoF)在其经典著作<DesignPatterns>一书中提出了“工厂模式”,这种模式在一定程度上有效的解决 ...

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

    二.依赖注入的应用模式 前面我们了解了依赖注入的基本概念,也对一些依赖注入框架进行了简单的介绍,这一章我们主要来讨论作为开发者如何利用依赖注入框架来实现依赖注入的设计思想. 1.     依赖注入的方 ...

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

    2.     AOP应用举例 在一般的应用程序开发中,有一些典型的AOP应用,使得开发者可以专注于业务逻辑本身,而不是与之完全无关的一些“方面”. l        首先就是关于前面介绍过的日志输出类 ...

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

    四.依赖注入对象的行为增强(AOP) 前面讲到,依赖注入框架的最鲜明的特点就是能够提供受容器管理的依赖对象,并且可以对对象提供行为增强(AOP)功能,所以这一章我们来讨论有关AOP的话题. 1.    ...

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

    三.依赖注入对象的Scope及其生命周期 在前面的章节我们讲到,依赖注入容器之所以能够区别于以往的ServiceLocator等容器,是在于其不但能够自动构建多层次的.完整的依赖关系图,并且可以管理依 ...

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

    3.2.    “好莱坞原则” 看了前面关于依赖注入概念的描述,我们来提炼出依赖注入的核心思想.如果说传统的组件间耦合方式,例如new.工厂模式等,是一种由开发者主动去构建依赖对象的话,那么依赖注入模 ...

随机推荐

  1. 04747_Java语言程序设计(一)_第1章_Java语言基础

    二进制0b开头 八进制0开头 十六进制0x开头 package com.jacky; public class Aserver { public static void main(String arg ...

  2. PHP 超强过滤函数

    PHP 超强过滤函数 你有每次要过滤的时候总是去翻曾经的过滤代码的时候么? 你有搜索过怎样防过滤,防攻击的PHP解决方法么? 你有对全然遵循'过滤输入,避免输出',Web界经典说辞么?     事实上 ...

  3. cocos2d-x绑定ccb文件

    首先,ccb文件是如何生成的,我就不多说了,大家可以搜下cocosbuilder,就能找的相关的教程,而通过cocosbuilder,我们可以省去了很多设计的麻烦,比如设计一个精灵的位置啥的,而通过c ...

  4. RocketMQ与Kafka对比(18项差异)评价版

    此文是rocketmq作者vintage.wang所写,对于每项对比,后面都增加了我的观点,有不对的地方,请各位指出. 淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用Mysql作为 ...

  5. 伪元素”:after” , “:before"

    伪元素就是源码html中不存在,而视觉上又存在的元素     简单用法: blockquote:before {      content: open-quote;      // 其他样式 } // ...

  6. 【Android类型SDK测试(二)】环境基础

    (一)语言 Android使用的Java语言,所以要测试Android类型的SDK,Java的基础知识还是需要的. 另外,Android中有NDK类型的编程,需要知道C相关的知识. (二)环境准备 A ...

  7. 调试 JavaScript 脚本

    随着 JavaScript 应用的复杂性逐渐提高,开发者需要有力的调试工具来帮助他们快速发现问题的原因,并且能高效地修复它.Chrome DevTools 提供了一系列实用的工具使得调试 JavaSc ...

  8. H5 progress标记

    进度条标记 示例:<progress class="processbar" id="processbar" max="100" val ...

  9. CentOS6.4 LAMP环境搭建

    网上的教程,不能按着抄打进去,这样会打乱你环境放置位置, 会导致配置路径会出问题. 要有一个环境目录优化, 把环境文件都装在/usr/local里面 首先,把安装文件rar都放置在/usr/local ...

  10. I/O事件

    I/O事件 最近在研究tornado和gevent,里面涉及了非阻塞I/O.在了解非阻塞I/O之前,需要先了解I/O事件 我们知道,内核有缓冲区.假设有两个进程A,B,进程B想读进程A写入的东西(即进 ...