Spring入門學習(AOP) 第十四節
阿新 • • 發佈:2019-01-06
Spring入門學習(AOP)
為什麼需要AOP
- 新建一個介面
ArithmeticCalculator.java
和它的實現類ArithmeticCalculatorImpl
在上述類中,當我們需要為這些類新增日誌時,需要在相應的業務邏輯中取新增,要修改時,可能也會涉及許多改動的地方。public interface ArithmeticCalculator { int add(int i, int j); int sub(int i, int j); int mul
一種方法是使用動態代理解決
- 新建一個代理類
ArithmeticCalculatorLoggingProxy
使用反射可以在方法執行前後做一些事,比如獲取方法名新增日誌處理,最後返回代理類。public class ArithmeticCalculatorLoggingProxy { // 要代理的物件 private ArithmeticCalculator target; public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) { this.target = target; } public ArithmeticCalculator getLoggingProxy() { ArithmeticCalculator proxy = null; // 代理物件由哪一個類載入器負責載入 ClassLoader loader = target.getClass().getClassLoader(); Class[] interfaces = new Class[]{ArithmeticCalculator.class}; // 當呼叫代理物件提供的方法時,該執行的程式碼 InvocationHandler h = new InvocationHandler() { /** * proxy: 正在返回的代理物件,一般情況下,在invoke方法中不使用該物件 * method: 正在被呼叫的方法 * args: 呼叫方法時,傳入的引數 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 一般在內部是不會使用proxy物件(自己呼叫自己了) // System.out.println(proxy.toString()); String methodName = method.getName(); // 日誌 System.out.println("the Methdo:"+methodName+"Begins with: "+Arrays.asList(args)); // 執行方法 Object result = method.invoke(target, args); System.out.println("The method "+methodName+"ends with "+result); return result; } }; proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h); return proxy; } }
- 我們註釋
ArithmeticCalculatorImpl
類方法中列印的資訊,建立測試方法,使用代理類新增日誌資訊:
測試結果:public class Main { public static void main(String[] args) { ArithmeticCalculator target = new ArithmeticCalculatorImpl(); ArithmeticCalculator proxy = new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy(); int result = proxy.add(2, 1); System.out.println("-->" + result); result = proxy.div(4, 2); System.out.println("-->" + result); } }
the Methdo:addBegins with: [2, 1] The method addends with 3 -->3 the Methdo:divBegins with: [4, 2] The method divends with 2 -->2
使用Spring AOP
AOP簡介
AOP術語
可以使用@AspectJ
註解宣告切面