用Java创建自己的AOP
介紹
如您所知,AOP是Spring框架提供的最好的功能之一,它在實現(xiàn)跨領(lǐng)域關(guān)注的同時提供了最大的靈活性。 您是否想到過AOP在Spring如何工作? 有時這是高級技術(shù)面試時要問的問題。 有時,僅涉及核心Java時,這個問題變得更加重要。 最近,我的一位朋友去參加采訪,他面臨一個尷尬的問題,即如何僅在核心Java中使用AOP而無需使用Spring和相關(guān)庫。 在本文中,我將為您提供有關(guān)如何僅在具有某些限制的情況下僅在核心Java中創(chuàng)建自己的AOP的概述。 這不是Spring AOP和Java AOP之間的比較研究。 但是,您可以使用適當(dāng)?shù)脑O(shè)計模式在一定程度上用Java實現(xiàn)AOP。
大家都知道AOP以及如何使用Spring框架使用AOP,本文將使您深入了解不使用Spring就能在Java中實現(xiàn)AOP的方法。 作為參考,Spring使用JDK代理和CGlib來提供AOP實現(xiàn)。 JDK動態(tài)代理提供了一種靈活的方法來掛鉤方法并以一定的限制執(zhí)行某些操作。 限制是應(yīng)該有一個接口,并且應(yīng)該有該接口的實現(xiàn)。 到目前為止,還不清楚。 讓我們舉個例子。 我們有一個計算器,通過它我們可以執(zhí)行一些數(shù)學(xué)運算。 讓我們考慮用一個數(shù)字除以另一個數(shù)字。 現(xiàn)在的問題是有人已經(jīng)在核心框架中提供了除法運算的實現(xiàn),是否有可能在該方法中進行劫持以執(zhí)行額外的驗證? 是的。 為此,我在下面的代碼片段中提供了這種簡單的情況。 基本的抽象代碼如下。
public interface Calculator {public int calculate( int a , int b); }該實現(xiàn)的代碼如下。
public class CalculatorImpl implements Calculator {@Overridepublic int calculate(int a, int b) {return a/b;} }想象一下,上面的代碼已凍結(jié),并且內(nèi)核中不能進行更多修改,但是您必須毫無問題地實現(xiàn)功能。 怎么做 ? 讓我們使用JDK動態(tài)代理的功能。
public class SomeHandler implements InvocationHandler {// Code omitted for simplicity…..@Overridepublic Object invoke(Object proxy, Method method, Object[] params) throws Throwable { // Your complex business validation and logicObject result = method.invoke(targetObject ,params);return result;}}讓我們來看一下使用我們的jdk動態(tài)代理來執(zhí)行所需功能的測試類。
public static void main(String[] args) {CalculatorImpl calcImpl = new CalculatorImpl();Calculator proxied = (Calculator) getProxy (Calculator.class, calcImpl, new SomeHandler(calcImpl));int result = proxied.calculate(20, 10);System.out.println("FInal Result :::" + result);}如您所見,我們只是通過簡單地實現(xiàn)了偉大的接口調(diào)用“ InvocationHandler ”而提供了一個掛鉤實現(xiàn)。 根據(jù)Java文檔,它處理代理實例上的方法調(diào)用。
現(xiàn)在,您已經(jīng)在上面看到了我們可以使用InvocationHandler's invoke()方法執(zhí)行某些操作來獲得所需的結(jié)果。 現(xiàn)在我們想到的問題是,在實際方法執(zhí)行之前和之后如何做些事情。 有可能在執(zhí)行方法之前做些什么然后在執(zhí)行該方法之后做些什么嗎? 為了使它更具體,我們可以添加多個aops(之前,之后,周圍)來掛鉤一個方法嗎? 我們可以通過制作簡化的代碼模板來實現(xiàn)。 讓我們按照以下步驟實現(xiàn)它。
簡要的技術(shù)實施
按照以下方式創(chuàng)建抽象處理程序。
public abstract class AbstractHandler implements InvocationHandler {private Object targetObject;public void setTargetObject(Object targetObject) {this.targetObject = targetObject;} }創(chuàng)建靈活的開發(fā)人員友好的處理程序,例如BeforeHandler和AfterHandler 。
apublic abstract class BeforeHandler extends AbstractHandler {public abstract void handleBefore(Object proxy, Method method, Object[] args);public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {handleBefore(proxy, method, args);return method.invoke(getTargetObject(), args);} }public abstract class AfterHandler extends AbstractHandler {public abstract void handleAfter(Object proxy, Method method, Object[] args);public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = method.invoke(getTargetObject(), args);handleAfter(proxy, method, args);return result;} }創(chuàng)建代理實用程序。
public class ProxyFactory {public static Object getProxy(Object targetObject,List<AbstractHandler> handlers) {//Code to get the proxyreturn proxyObject;} else {return targetObject;}} }現(xiàn)在,下面給出了測試工具代碼段。
CalculatorImpl calcImpl = new CalculatorImpl(); BeforeHandler before = new BeforeHandlerImpl(); AfterHandler after = new AfterHandlerImpl(); List<AbstractHandler> handlers = new ArrayList<AbstractHandler>(); handlers.add(before); handlers.add(after); Calculator proxy = (Calculator) ProxyFactory.getProxy(calcImpl,handlers); int result = proxy.calculate(20, 10);組態(tài)
以上所有代碼段都很簡短,以使您對結(jié)構(gòu)實現(xiàn)更加清楚。 進行實際的品味/測試來實現(xiàn)現(xiàn)實總是更好。 從下面的github鏈接下載完整的項目,并在您喜歡的Java編輯器中對其進行配置,然后運行測試類以查看效果。
- https://github.com/debjava/aopusingjdkdynamicproxy
結(jié)論
希望您喜歡我關(guān)于Java的AOP的小文章,發(fā)表一些評論以豐富和增強雙方的知識。 在本文之前和之后的文章中,我將“ Around”和“ Throw” AOP留給讀者。
翻譯自: https://www.javacodegeeks.com/2015/03/create-your-own-aop-in-java.html
總結(jié)
以上是生活随笔為你收集整理的用Java创建自己的AOP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 负债100万,不知道怎么办了?
- 下一篇: JavaFX技巧18:路径剪切