`

AOP分解

阅读更多

JDK动态代理
   
在JDK 1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例。在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在我们终于发现动 态代理是实现AOP的绝好底层技术。
    JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。其中 InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,在并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一 起。
   而Proxy为InvocationHandler实现类动态创建一个符合某一接口的代理实例。这样讲一定很抽象,我们马上着手动用Proxy和 InvocationHandler这两个魔法戒对上一节中的性能监视代码进行AOP式的改造。
    首先,我们从业务类ForumServiceImpl 中删除性能监视的横切代码,使ForumServiceImpl只负责具体的业务逻辑,如所示:
代 码清单 5 ForumServiceImpl:移除性能监视横切代码

 

package com.baobaotao.proxy;

public class ForumServiceImpl implements ForumService {

 public void removeTopic(int topicId) {
 ①
 System.out.println("模拟删除Topic记录:"+topicId);
 try {
 Thread.currentThread().sleep(20);
 } catch (Exception e) {
 throw new RuntimeException(e);
 }
 ②
 }
 public void removeForum(int forumId) {
 ①
 System.out.println("模拟删除Forum记录:"+forumId);
 try {
 Thread.currentThread().sleep(40);
 } catch (Exception e) {
 throw new RuntimeException(e);
 }
 ②
 }
}

 

 在代码清单 5中的①和②处,原来的性能监视代码被移除了,我们只保留了真正的业务逻辑。
    从业务类中移除的横切代码当然还得找到一个寄居之所,InvocationHandler就是横切代码的家园乐土,我们将性能监视的代码安置在 PerformaceHandler中,如代码清单 6所示:
代码清单 6 PerformaceHandler

package com.baobaotao.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class PerformaceHandler implements InvocationHandler {
 private Object target;
 public PerformaceHandler(Object target){//①target为目标的业务类
 this.target = target;
 }
 public Object invoke(Object proxy, Method method, Object[] args)
 throws Throwable {
 PerformanceMonitor.begin(target.getClass().getName()+"."+ method.getName());
 Object bj = method.invoke(target, args);//②通过反射方法调用目标业务类的业务方法
 PerformanceMonitor.end();
 return obj;
 }
}

  粗体部分的代码为性能监视的横切代码,我们发现,横切代码只出现一次,而不是原来那样星洒各处。大家注意②处的method.invoke(),该语句通 过反射的机制调用目标对象的方法,这样InvocationHandler的invoke(Object proxy, Method method, Object[] args)方法就将横切代码和目标业务类代码编织到一起了,所以我们可以将InvocationHandler看成是业务逻辑和横切逻辑的编织器。下面, 我们对这段代码做进一步的说明。
首先,我们实现InvocationHandler接口,该接口定义了一个 invoke(Object proxy, Method method, Object[] args)的方法,proxy是代理实例,一般不会用到;method是代理实例上的方法,通过它可以发起对目标类的反射调用;args是通过代理类传入 的方法参数,在反射调用时使用。
    此外,我们在构造函数里通过target传入真实的目标对象,如①处所示,在接口方法invoke(Object proxy, Method method, Object[] args)里,将目标类实例传给method.invoke()方法,通过反射调用目标类方法,如②所示。
    下面,我们通过Proxy结合PerformaceHandler创建ForumService接口的代理实例,如代码清单 7所示:
代码清单 7 TestForumService:创建代理实例

package com.baobaotao.proxy;
import java.lang.reflect.Proxy;
public class TestForumService {
 public static void main(String[] args) {
 ForumService target = new ForumServiceImpl();//①目标业务类
//② 将目标业务类和横切代码编织到一起
 PerformaceHandler handler = new PerformaceHandler(target);
 //③为编织了目标业务类逻辑和性能监视横切逻辑的handler创建代理类
 ForumService proxy = (ForumService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
 target.getClass().getInterfaces(),
 handler);
 //④ 操作代理实例
 proxy.removeForum(10);
 proxy.removeTopic(1012);
 }
}

   上面的代码完成了业务类代码和横切代码编织和接口代理实例生成的工作,其中在②处,我们将ForumService实例编织为一个包含性能监视逻辑的 PerformaceHandler实例,然后在③处,通过Proxy的静态方法newProxyInstance()为融合了业务类逻辑和性能监视逻辑 的handler创建一个ForumService接口的代理实例,该方法的第一个入参为类加载器,第二个入参为创建的代理实例所要实现的一组接口,第三 个参数是整合了业务逻辑和横切逻辑的编织器对象。
按照③处的设置方式,这个代理实例就实现了目标业务类的所有接口,也即 ForumServiceImpl的ForumService接口。这样,我们就可以按照调用ForumService接口的实例相同的方式调用代理实 例,如④所示。运行以上的代码,输出以下的信息:

begin monitor...
模拟删除Forum记录:10
end monitor...
com.baobaotao.proxy.ForumServiceImpl.removeForum花费47毫秒。

begin monitor...
模拟删除Topic记录:1012
end monitor...
com.baobaotao.proxy.ForumServiceImpl.removeTopic花费26毫秒。


 


我们发现,程序的运行效果和直接在业务类中编写性能监视逻辑的效果一致,但是在这里,原来分散的横切逻辑代码已经被我们抽取到 PerformaceHandler中。当其它业务类(如UserService、SystemService等)的业务方法也需要使用性能监视时,我们 只要按照以上的方式,分别为它们创建代理对象就可以了。下面,我们用时序图描述调用关系,进一步代理实例的本质,如图1所示:
 
                                图 1代理实例的时序图
    我们在上图中特别使用虚线阴影的方式对通过代理器创建的ForumService实例进行凸显,该实例内部利用PerformaceHandler整合横 切逻辑和业务逻辑。调用者调用代理对象的的removeForum()和removeTopic()方法时,上图的内部调用时序清晰地告诉了我们实际上所 发生的一切。  

  • 大小: 5.5 KB
分享到:
评论

相关推荐

    Spring AOP教程

    Spring框架的关键组件之一是面向方面编程(AOP)框架。 面向方面的编程需要将程序逻辑分解成不同的部分。 此教程将通过简单实用的方法来学习Spring框架提供的AOP/面向方面编程。

    深入理解Android之AOP

    首先,面向对象编程(OOP)是一种通过对象来思考问题和组织程序的方法,它把问题分解为各种各样的对象,而对象则包含数据以及可以操作数据的方法。例如,在Android框架中,Activity、Service、BroadcastReceiver等都...

    Java JDK 实现AOP

    ### Java JDK 实现AOP详解 #### AOP的起源与发展 面向方面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,由施乐公司帕洛阿尔托研究中心(Xerox PARC)在20世纪90年代发明。AOP的初衷是为了更好地...

    AOP及其Java实现机制.doc

    传统的编程技术通过分解的方式将一个复杂的软件系统拆分成相对较小、易于管理和理解的模块。然而,在实际开发过程中,一些跨模块的行为(如日志记录、事务管理等)难以封装在单一的模块中,导致这些功能散布在整个...

    chapter05_aop地铁_用SpringAOP模拟乘坐地铁服务_

    总的来说,通过Spring AOP,我们可以优雅地将地铁服务的各个部分分解为独立的关注点,并在不侵入业务逻辑的情况下进行管理。这种方式提高了代码的可维护性和可重用性,使得系统更加模块化。在本教程的"chapter05"中...

    Aop例子 demo

    在面向切面编程中,切面将业务逻辑中的关注点分解为可重用的部分,这些部分可以独立于主业务逻辑进行修改和维护。 2. **连接点(Join Point)**:连接点是程序执行过程中的特定点,比如方法调用、异常处理、类初始...

    aop设计专用日文资料

    - **系统的对象化分解**:将整个系统拆分为多个相互协作的对象。 - **对象间的通信**:系统通过对象间的消息传递来实现协同工作。 - **一致性模型**:从需求分析到最终实现,均采用一致的模型进行描述。 - **功能...

    基于动态AOP的动态体系结构

    基于构件的软件开发(Component-Based Software Development, CBSD)是一种将软件开发分解为一系列可重用组件的方法。这种方法可以提高软件的开发效率和质量,减少开发周期,并有助于构建更加灵活和可扩展的软件系统...

    第四章:Spring AOP API 设计模式1

    构建器模式将复杂对象的构建过程分解,方便对各部分独立处理,从而降低了代码的复杂度。 3. **工厂方法模式(Factory Method)**:Spring AOP中的`ProxyFactory`是一个典型的工厂方法模式实现,它根据不同的条件...

    Spring 使用AspectJ 实现 AOP之前置通知小例子

    上面的表达式可以分解为: - `*`:代表任意返回类型 - `com.example.service.*`:代表`com.example.service`包及其子包下的所有类 - `.*`:代表类中的所有方法 - `(..)`:代表方法的任意参数 5. **注册切面**:...

    SpringAOP实现.docx

    而在AOP中,关注点被分解为独立的“切面”,这些切面可以包含业务逻辑中的关注点,如日志、安全检查等。切面可以横切多个对象,降低了代码的耦合度。 2. **导入AOP依赖** 在Spring中实现AOP,首先需要在项目中引入...

    面向方法编程AOP学习之二 —— “原始时代”

    在这一阶段,程序员们开始意识到将程序分解为一系列独立的功能模块或方法的重要性,但尚未发展出如面向切面编程(Aspect-Oriented Programming,AOP)等更为先进的技术。 在面向方法编程的“原始时代”,开发者主要...

    AOP编程模式与标准java的应用

    6. **支配性分解(Dominant Decomposition)**:是软件模块化的主要方式,传统上通过类、接口等方式实现。 7. **横切关注点(Crosscutting Concerns)**:指那些无法通过传统的模块化方式完全捕捉的关注点,它们的...

    AOP高级氧化[整理].pdf

    AOP代表Advanced Oxidation Processes,它主要利用高度氧化性物质,如臭氧(O3),来破坏和分解水中的有机污染物。这种技术在环保和可持续发展领域具有重要意义,因为它能有效地去除污染物,降低COD(化学需氧量)至...

    SpringAOP介绍及源码分析

    如果说面向对象编程可以对业务需求进行很好的分解使之模块化;那么面向切面编程AOP(Aspect-OrientedProgramming)则可以对系统需求进行很好的模软件开发经历了从汇编语言到高级语言和从过程化编程到面向对象编程;...

    Spring核心IoC和AOP的理解

    AOP的主要思想是将程序分解成各个切面,每个切面都代表了某个特定的关注点。AOP的优点: 1. 提供了声明式事务管理,简化了事务处理的逻辑。 2. 支持用户自定义的切面,提高了程序的可扩展性。 三、Spring框架的...

    spring-aop:易百教程网-Spring AOP教程源代码(http

    SpringAOP 易百教程网-Spring AOP教程源代码( ) Spring框架的关键组件之一是面向方面编程(AOP)框架。面向方面的编程需要将程序逻辑分解成不同的部分。 此教程将通过简单实用的方法来学习Spring框架提供的AOP /...

Global site tag (gtag.js) - Google Analytics