JAVA網課,Spring入門第十七課

 2023-11-07 阅读 28 评论 0

摘要:AOP編程 JAVA網課,問題: 代碼混亂: 越來越多的非業務需求(日志和驗證等)加入后,原有的業務方法急劇膨脹,每個方法在處理核心邏輯的同事還必須兼顧其他多個關注點。 代碼分散:以日志需求為例,只是為了滿足這個單一需

AOP編程

JAVA網課,問題:

代碼混亂:

越來越多的非業務需求(日志和驗證等)加入后,原有的業務方法急劇膨脹,每個方法在處理核心邏輯的同事還必須兼顧其他多個關注點。

代碼分散:以日志需求為例,只是為了滿足這個單一需求,就不得不在多個模塊(方法)里面多次重復相同的日志代碼,如果日志需求發生變化,必須修改所有模塊。

先看使用動態代理:

package logan.study.aop.helloworld;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);}
package logan.study.aop.helloworld;public class ArithmeticCalculatorImpl implements ArithmeticCalculator {@Overridepublic int add(int i, int j) {// TODO Auto-generated method stubint result = i + j;return result;}@Overridepublic int sub(int i, int j) {// TODO Auto-generated method stubint result = i - j;return result;}@Overridepublic int mul(int i, int j) {// TODO Auto-generated method stubint result = i * j;return result;}@Overridepublic int div(int i, int j) {// TODO Auto-generated method stubint result = i / j;return result;}}
package logan.study.aop.helloworld;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;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:正在返回的那個對象,一般情況下,在invok方法中都不使用該對象* method:正在被調用的方法* args:調用方法時傳入的參數*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// TODO Auto-generated method stubString methodName = method.getName();//日志System.out.println("The method "+ methodName + "begin with " + Arrays.asList(args));//執行方法Object result = method.invoke(target, args);//日志System.out.println("The method " + methodName + "end with result = " + result);//返回return result;}};proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);return proxy;}}
package logan.study.aop.helloworld;public class Main {public static void main(String[] args) {// TODO Auto-generated method stubArithmeticCalculator target = new ArithmeticCalculatorImpl();ArithmeticCalculator proxy =  new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy();int result = proxy.add(1, 2);System.out.println("-->"+result);result = proxy.div(8, 2);System.out.println("-->"+result);}}

返回的結果:

The method addbegin with [1, 2]
The method addend with result = 3
-->3
The method divbegin with [8, 2]
The method divend with result = 4
-->4

但是使用動態代理比較麻煩,有沒有更簡單的方法來實現呢?

AOP(Aspect-Oriented-Programming,面向切面編程)是一種新的方法論,是對傳統OOP(Object-Oriented-Programming,面向對象編程)的補充。

AOP的主要編程對象是切面(Aspect),而切面是模塊化橫切關注點。

在應用AOP編程時,仍然需要定義公共功能,但是可以明確地定義這個功能在哪里,以什么方式應用,并且不必修改受影響的類,這樣一來,橫切關注點就被模塊化到特殊的對象(切面)里。

AOP好處:

-每個事物邏輯錯位與一個位置,代碼不分散,便于維護和升級

-業務模塊更簡潔,只包含核心的業務代碼

AOP術語

切面(Aspect):橫切關注點(跨越應用程序多個模塊的功能)被模塊化的特殊對象。

通知(Advice):切面必須要完成的工作。

目標(Target):被通知的對象。

代理(Proxy):向目標對象應用通知之后創建的對象。

連接點(Joinpoint):程序執行的每個特定位置:如類某個方法調用前,調用后,方法拋出異常等等,連接點由兩個信息確定:方法表示的程序的執行點,相對點表示的方位,例如ArithmeticCalculator#add()方法執行前的連接點執行點為ArithmeticCalculator#add();方位為該方法執行前的位置。

切點(pointcut):每個類都擁有多個連接點,例如:ArithmethicCalculator的所有方法實際上都是連接點,即連接點是程序類中客觀存在的事務,AOP通過切點定位到特定的連接點。類比:連接點相當于數據庫中的記錄,切點相當于查詢條件,切點和連接點不是一對一關系,一個切點匹配多個連接點,切點通過org.springframework.aop.Pointcut接口進行描述,它使用類和方法作為連接點的查詢條件。

轉載于:https://www.cnblogs.com/LoganChen/p/6913060.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/167108.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息