资讯详情

手把手教你用 Java 实现 AOP

2017-04-19 阅读:137 来源:哈尔滨今日灵图
进入>

介绍

众所周知,AOP(面向切面编程)是Spring框架的特色功能之一。通过设置横切关注点(crosscuttingconcerns),AOP提供了极高的扩展性。那AOP在Spring中是怎样运作的呢?当你只能使用corejava,却需要AOP技术时,这个问题的解答变得极为关键。不仅如此,在高级技术岗位的面试中,此类问题也常作为考题出现。这不,我的朋友最近参加了一个面试,就被问到了这样一个棘手的问题——如何在不使用Spring及相关库,只用coreJava的条件下实现AOP。因此,我将在本文中提供一份大纲,帮助大家了解如何只用coreJava实现一个AOP(当然啦,这种AOP在功能上有一定的局限性)。注意,本文不是一篇有关SpringAOP与JavaAOP的对比研究,而是有关在coreJava中借助固有的设计模式实现AOP的教程。

想必读者已经知道AOP是什么,也知道在Spring框架中如何使用它,因此本文只着眼于如何在不用Spring的前提下实现AOP。首先,我们得知道,Spring是借助了JDKproxy和CGlib两种技术实现AOP的。JDKdynamicproxy提供了一种灵活的方式来hook一个方法并执行指定的操作,但执行操作时得有一个限制条件:必须先提供一个相关的接口以及该接口的实现类。实践出真知,让我们透过一个案例来理解这句吧!现在有一个计算器程序,用于完成一些数学运算。让我们来考虑下除法功能,此时的问题是:如果coreframework已经具备了一份实现除法的代码,我们能否在代码执行时劫持(highjack)它并执行额外的校验呢?答案是肯定的,我将用下面提供的代码片段来证明这点。首先来看基础接口的代码:

publicinterfaceCalculator{

publicintcalculate(inta,intb);

}

该接口实现类的代码如下:

publicclassCalculatorImplimplementsCalculator{

@Override

publicintcalculate(inta,intb){

returna/b;

}

}

假设我们既不能修该上面的代码,也不能对核心库进行任何改动,怎样才能完美地实现校验功能呢?不如试下JDKdynamicproxy的功能吧。

publicclassSomeHandlerimplementsInvocationHandler{

//Codeomittedforsimplicity…..

@Override

publicObjectinvoke(Objectproxy,Methodmethod,Object[]params)throwsThrowable{

//Yourplexbusinessvalidationandlogic

Objectresult=method.invoke(targetObject,params);

returnresult;

}

}

让我们通过测试类来看看由JDKdynamicproxy实现的校验功能的效果如何。

publicstaticvoidmain(String[]args){

CalculatorImplcalcImpl=newCalculatorImpl();

Calculatorproxied=(Calculator)ProxyFactory.getProxy(Calculator.class,calcImpl,

newSomeHandler(calcImpl));

intresult=proxied.calculate(20,10);

System.out.println("FInalResult:::"+result);

}

从结果可以看出,简单地实现功能强大的InvocationHandler接口,我们便能得到一个hookingimplementation。按照JDK文档的描述,InvocationHandler接口是借助一个代理实例(proxyinstance)来处理一个方法调用的。

现在我们已经知道,InvocationHandler的invoke()方法能够帮助我们解决问题。那么再来解决一个新问题——怎样才能在方法执行的前后执行操作呢?说的更具体一些,我们能通过添加多个aop(before、after、around)来hook一个方法吗(译注:原文为addmultipleaops,但我认为Handler是充当Aspect的角色)?答案同样是肯定的。按照以下的步骤建立一个精简的代码模板便能满足这样的需求:

1.

创建一个抽象类,用于将aop应用于目标对象上。

2.

创建名为BeforeHandler和AfterHandler的两个aop。前者在方法执行之前工作,而后者则在方法执行结束后工作。

3.

创建一个代理类,使所有的aophandler和目标对象只需作为参数传入,就能创建一个hook。

4.

加入你自己的业务逻辑或者横切关注点。

5.

最后,通过传入相关的参数创建代理对象(proxyobject)。

技术实现概要

(译注:此处是核心代码片段,如果想运行该实例,需进入下方提供的链接下载完整代码)

创建一个handler的抽象类:

publicabstractclassAbstractHandlerimplementsInvocationHandler{

privateObjecttargetObject;

publicvoidsetTargetObject(ObjecttargetObject){

this.targetObject=targetObject;

}

}

创建名为BeforeHandler和AfterHandler的两个易扩展的handler抽象类:

publicabstractclassBeforeHandlerextendsAbstractHandler{

publicabstractvoidhandleBefore(Objectproxy,Methodmethod,Object[]args);

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{

handleBefore(proxy,method,args);

returnmethod.invoke(getTargetObject(),args);

}

}

publicabstractclassAfterHandlerextendsAbstractHandler{

publicabstractvoidhandleAfter(Objectproxy,Methodmethod,Object[]args);

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{

Objectresult=method.invoke(getTargetObject(),args);

handleAfter(proxy,method,args);

returnresult;

}

}

创建Proxy的工厂类:

publicclassProxyFactory{

publicstaticObjectgetProxy(ObjecttargetObject,

Listhandlers){

//Codetogettheproxy

returnproxyObject;

}else{

returntargetObject;

}

}

}

以下为测试代码:

CalculatorImplcalcImpl=newCalculatorImpl();

BeforeHandlerbefore=newBeforeHandlerImpl();

AfterHandlerafter=newAfterHandlerImpl();

Listhandlers=newArrayList();

handlers.add(before);

handlers.add(after);

Calculatorproxy=(Calculator)ProxyFactory.getProxy(calcImpl,

handlers);

intresult=proxy.calculate(20,10);

配置

以上的代码片段简明扼要地解释了AOP在结构上的实现(structuralimplementation)。当然,如果能通过实际的测试将其运用到现实中去,那就再好不过了。读者可在下面的链接中获取完整的工程文件,并在Java编辑器中配置它们,最后通过其中的测试类来检验效果。

总结

希望这篇简短的有关AOP文章能够帮助到大家。需说明的是,本文只实现了before和after两种aop,而另外两种,即“Around”和“Throw”,则希望读者自行完成。

请联系网站客服,了解详细的优惠课程信息~

优质、权威、便捷、省心

加载全文

免责声明:本站部分内容、图片来自用户自主上传,如果您对本站信息资源版权的归属问题存有异议,请您致信,我们会立即做出答复并及时解决。如果您认为本站有侵犯您权益的行为,请通知我们,我们一定根据实际情况及时处理。

以上是哈尔滨今日灵图为大家整理的有关手把手教你用 Java 实现 AOP的全部内容,更多精彩请访问学习资讯新闻专栏。

相关课程

更多>
2020猎学网广告栏
申请课程免费试听名额

课程顾问24小时内联系您

你好

顾问将于24小时内联系您!

确定
在线咨询 微信咨询 立即报名
申请1对1课程顾问咨询服务
×
你好

顾问将于24小时内联系您!

确定
哈尔滨猎学网 >哈尔滨今日灵图 >手把手教你用 Java 实现 AOP