javascript
Spring框架学习笔记(7)——代理对象实现AOP
AOP(面向切面編程)
AOP(Aspect-Oriented Programming, 面向切面編程): 是一種新的方法論, 是對傳統 OOP(Object-Oriented Programming, 面向對象編程) 的補充.
AOP 的主要編程對象是切面(aspect), 而切面模塊化橫切關注點.
在應用 AOP 編程時, 仍然需要定義公共功能, 但可以明確的定義這個功能在哪里, 以什么方式應用, 并且不必修改受影響的類. 這樣一來橫切關注點就被模塊化到特殊的對象(切面)里.
AOP 的好處:
每個事物邏輯位于一個位置, 代碼不分散, 便于維護和升級
業務模塊更簡潔, 只包含核心業務代碼.
?
AOP術語
切面(Aspect):? 橫切關注點(跨越應用程序多個模塊的功能)被模塊化的特殊對象
通知(Advice):? 切面必須要完成的工作
目標(Target): 被通知的對象
代理(Proxy): 向目標對象應用通知之后創建的對象
連接點(Joinpoint):程序執行的某個特定位置:如類某個方法調用前、調用后、方法拋出異常后等。連接點由兩個信息確定:方法表示的程序執行點;相對點表示的方位。例如 ArithmethicCalculator#add() 方法執行前的連接點,執行點為 ArithmethicCalculator#add(); 方位為該方法執行前的位置
切點(pointcut):每個類都擁有多個連接點:例如 ArithmethicCalculator 的所有方法實際上都是連接點,即連接點是程序類中客觀存在的事務。AOP 通過切點定位到特定的連接點。類比:連接點相當于數據庫中的記錄,切點相當于查詢條件。切點和連接點不是一對一的關系,一個切點匹配多個連接點,切點通過 org.springframework.aop.Pointcut 接口進行描述,它使用類和方法作為連接點的查詢條件。
?
代理對象實現AOP的DEMO
DEMO中實現了一個簡易計算器,有加減乘除四個方法
現在要在四個方法執行前和執行后添加一段輸出語句模擬日志
如果不使用AOP就會出現下面的情況
?
public int add(int i, int j) {System.out.println("The method add begins with [" + i + "," + j + "]");int result = i + j;System.out.println("The method add ends with " + result);return result; }?
方法會變得臃腫且業務不明顯,這里的日志打印就可以當做AOP的一個切面拿出來,方法里只留業務邏輯,如上圖。
使用代理對象實現AOP
?
MAIN方法:
public class Main {public static void main(String[] args) {ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorImpl();arithmeticCalculator = new ArithmeticCalculatorLoggingProxy(arithmeticCalculator).getLoggingProxy();int result = arithmeticCalculator.add(11, 12);System.out.println("result:" + result);result = arithmeticCalculator.div(21, 3);System.out.println("result:" + result);}}接口方法:
public interface ArithmeticCalculator {int add(int i, int j);int sub(int i, int j);int mul(int i, int j);int div(int i, int j);}實現方法:
@Component("arithmeticCalculator") public class ArithmeticCalculatorImpl implements ArithmeticCalculator {@Overridepublic int add(int i, int j) {int result = i + j;return result;}@Overridepublic int sub(int i, int j) {int result = i - j;return result;}@Overridepublic int mul(int i, int j) {int result = i * j;return result;}@Overridepublic int div(int i, int j) {int result = i / j;return result;}}代理對象:
public class ArithmeticCalculatorLoggingProxy {//要代理的對象private ArithmeticCalculator target;public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {super();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: 代理對象。 一般不使用該對象* method: 正在被調用的方法* args: 調用方法傳入的參數*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {String methodName = method.getName();//打印日志System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args));//調用目標方法Object result = null;try {//前置通知result = method.invoke(target, args);//返回通知, 可以訪問到方法的返回值} catch (NullPointerException e) {e.printStackTrace();//異常通知, 可以訪問到方法出現的異常 }//后置通知. 因為方法可以能會出異常, 所以訪問不到方法的返回值//打印日志System.out.println("[after] The method ends with " + result);return result;}};/*** loader: 代理對象使用的類加載器。 * interfaces: 指定代理對象的類型. 即代理代理對象中可以有哪些方法. * h: 當具體調用代理對象的方法時, 應該如何進行響應, 實際上就是調用 InvocationHandler 的 invoke 方法*/proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);return proxy;} }使用代理對象實現AOP雖然可以滿足需求,但是較為復雜,而Spring提供一種簡單的實現AOP的方法AspectJ
AspectJ:Java 社區里最完整最流行的 AOP 框架.
在 Spring2.0 以上版本中, 可以使用基于 AspectJ 注解或基于 XML 配置的 AOP
所以實際開發中用AspectJ來實現AOP即可。
轉載于:https://www.cnblogs.com/huangjian2/p/6273914.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Spring框架学习笔记(7)——代理对象实现AOP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷 P 3379 【模板】最近公共祖
- 下一篇: javascript 表达式和运算符 (