四、依赖注入对象的行为增强(AOP)

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

1.     对依赖对象进行行为增强

所谓AOP,就是Aspect Oriented Programming(面向方面的编程),核心思想是把一个“方面”独立出来,从而实现组件间的松耦合。也许有些晦涩难懂,所以我们还是看个简单的例子。

在我们的银行依赖中,假设有个需求,即在每一笔取款业务的前后都要输出日志信息。因此我们需要这样修改我们的代码:

public class BankICBC implements Bank {

private static Logger logger = Logger.getLogger(Bank.class.getName());

@Override

public Cash withDraw(DepositBook depositBook, BigDecimal amount) {

logger.log(Level.INFO, "withdraws starting...");

// ……

logger.log(Level.INFO, "withdraws ended…");

}

}

可以看到,我们为了实现这个需求需要在其中加入定义logger、输出日志等代码。而这些代码,就是我们所说的独立的“方面”。为什么这么说呢?因为日志的输出工作,是与开发者真正要做的取款业务完全没有关系的。再假设,如果我们需要在很多其它地方也要做同样的日志处理,而这样的处理又完全不依赖于那些地方的逻辑,则我们需要打开全部的代码页,不分情况的Ctrl+C和Ctrl+V,这无疑给开发和维护带来了不小的困扰。

因此AOP的出现,就可以将这个独立的日志处理的“方面”从实际的依赖对象里分离开来,而在依赖对象在运行的时候,这个“方面”又可以加到依赖对象身上得以运行,也就是我们所说的依赖对象的行为被增强了,因为它的行为不但实现了它本身的逻辑,而且也实现了被增强的其它“方面”的逻辑。而在AOP体系内,用以将其它“方面”的逻辑增强到某对象上的组件往往被称作Interceptor(拦截器)。

Spring、Seam和Guice都提供了相应的拦截器定义方式,由于Seam是基于原注解模式的定义方法,在开发者使用时稍有不便,因此我们这里以Spring为例简单介绍一下如何将刚才的“日志处理方面”应用到我们的程序当中。

首先我们将“日志处理方面”分离出来作为一个独立的类,这个类即是被独立出来的“方面”。

public class LogInterceptor {

private static Logger logger =
Logger.getLogger(LogInterceptor.class.getName());

public Object log(ProceedingJoinPoint call)
throws Throwable {

logger.log(Level.INFO, "withdraws
starting...");

try {

return call.proceed();

} finally {

logger.log(Level.INFO, "withdraws
ended...");

}

}

}

Spring提供了很多种拦截器组装方式,这里我们采用XML配置的方式将这个“方面”增强到我们的银行依赖对象上:

<beans>

<!-- …… -->

<!-- 这里将“方面”类声明为Spring管理的依赖 -->

<bean id="logger"
class="tutorial.di.ch01.LogInterceptor"/>

  <!-- 这里将所声明的“方面”增强到需要的地方 -->

<aop:config>

<aop:aspect ref="logger">

<aop:pointcut
id="pointcuts.withdrawMethod"

expression="execution(*
tutorial.di.ch01.BankICBC.withDraw(..))"
/>

<aop:around
pointcut-ref="pointcuts.withdrawMethod " method="log"/>

</aop:aspect>

</aop:config>

</beans>

此后原先的BankICBC类就不需要再写任何的关于日志输出的代码,就可以将该功能导入进来了。反之如果想去掉这个需求,同样不需要变更BankICBC类,只将拦截器的配置删除即可,从而大大降低了程序逻辑与其它“方面”的耦合度。

注意所有AOP功能的底层实现都是靠Java的动态代理机制实现的,往往是基于JDK自身的代理类,或者是Javassist、CGLIB工具等,因此AOP的作用对象不能是私有方法、静态方法以及final方法。

依赖注入及AOP简述(十二)——依赖注入对象的行为增强(AOP) .的更多相关文章

  1. aop学习总结二------使用cglib动态代理简单实现aop功能

    aop学习总结二------使用cglib动态代理简单实现aop功能 模拟业务需求: 1.拦截所有业务方法 2.判断用户是否有权限,有权限就允许用户执行业务方法,无权限不允许用户执行业务方法 (判断是 ...

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

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

  3. WPF入门教程系列十二——依赖属性(二)

    二. 依赖属性的优先级 由于WPF 允许我们可以在多个地方设置依赖属性的值,所以我们就必须要用一个标准来保证值的优先级别.比如下面的例子中,我们在三个地方设置了按钮的背景颜色,那么哪一个设置才会是最终 ...

  4. 【十二】注入框架RoboGuice使用:(Your First Injected ContentProvider)

    上一篇我们简单的介绍了一下RoboGuice的使用([十一]注入框架RoboGuice使用:(Your First Injection into a Custom View class)),今天我们来 ...

  5. Spring Aop(十二)——编程式的创建Aop代理之AspectjProxyFactory

    转发地址:https://www.iteye.com/blog/elim-2397922 编程式的创建Aop代理之AspectjProxyFactory 之前已经介绍了一款编程式的创建Aop代理的工厂 ...

  6. 【emWin】例程二十二:窗口对象——Framewin

    简介: 框架窗口为您的应用提供一个PC 应用程序的窗口外观.这些窗口由周围框架.标题栏和用户区组成. 触摸校准(上电可选择是否进入校准界面) 截图 实验指导书及代码包下载: 链接:http://pan ...

  7. 【emWin】例程三十二:窗口对象———Progbar

    简介: 进度条通常在应用程序中用于实现虚拟化:本例程实现液晶亮度显示 . 触摸校准(上电可选择是否进入校准界面) 实验现象: 实验指导书及代码包下载: 链接:http://pan.baidu.com/ ...

  8. ASP入门(十二)-Application对象

    在一起协同工作以完成某项任务的一组ASP文件称为一个应用程序.Application 对象用于把这些文件捆绑在一起. Application 对象用于在整个应用程序生存期间保存信息. Applicat ...

  9. C++(三十二) — 常对象、常成员变量、常成员函数

    常量:对于既需要共享.又需要防止改变的数据.在程序运行期间不可改变. const 修饰的是对象中的 this 指针.所以不能被修改. 1.常对象 数据成员值在对象的整个生存期内不能改变.在定义时必须初 ...

  10. Sql注入_mysql盲注__二次注入

    sleep盲注攻击 Sleep延迟:延迟盲注 If(条件,true,false): 条件成立,返回第二个参数,反之第三个参数 举例1:length id=1 union select 1,2,slee ...

随机推荐

  1. Tip.It诞生记

    灵光一闪 之所以想做 Tip.It,完全是受自己初到北京时找房子各种痛苦的启发,当时为了跳过中介租房子,去58同城,豆瓣等各种网站去看房子,比如说下图就是一个典型的58同城的租房页面. 可以看到电话号 ...

  2. WorkFlow4.0--入门到精通系列-专题索引

    原文地址:http://www.cnblogs.com/hegezhou_hot/archive/2011/06/15/2081405.html 开篇 首先.非常感谢大家的支持和厚爱,才有了这个系列, ...

  3. 在PHP中处理表单之—Checkbox

    原文翻译自:http://www.html-form-guide.com/php-form/php-form-checkbox.html 单个checkbox  形如: <form action ...

  4. poj 1887 Testing the CATCHER_最长上升子序列

    题意:题目太长没看,直接看输入输出猜出是最长下降子序列 用了以前的代码直接a了,做法类似贪心,把最小的顺序数存在数组里面,每次二分更新数组得出最长上升子序列 #include<iostream& ...

  5. SecureCRT按退格键出现^H问题解决

    解决办法一: 解决办法二: ctrl+backspace.即是返回

  6. OAuth2.0 错误码

    http://open.taobao.com/doc/detail.htm?id=118 OAuth2.0 错误码 新浪微博OAuth2.0实现中,授权服务器在接收到验证授权请求时,会按照OAuth2 ...

  7. HDU2054_A == B ?【模拟题】【大数】【水的问题】

    A == B ? Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  8. UVA 12545 Bits Equalizer

    题意: 两个等长的字符串p和q,p有‘0’,‘1’,‘?’组成,q由‘0’,‘1’组成.有三种操作:1.将‘?’变成0:2.将‘?’变成‘1’:3.交换同一字符串任意两个位置上的字符.问有p变到q最少 ...

  9. Android 打开系统最近任务及最近应用方法

    Class serviceManagerClass; try { serviceManagerClass = Class.forName("android.os.ServiceManager ...

  10. oracle权限的分配

    一.创建 sys:   //系统管理员,拥有最高权限 system://本地管理员,次高权限 scott: //普通用户,密码默认为tiger,默认未解锁 二.登陆 sqlplus / as sysd ...