當前位置:編程學習大全網 - 編程語言 - spring aop是用什麽實現的?

spring aop是用什麽實現的?

在學習代理模式的時候,我了解到代理模式可以分為動態代理和靜態代理。現在我們將基於代理模式實現我們自己的AOP框架,然後研究Spring AOP的實現原理。

首先,它是通過靜態代理實現的。靜態代理的關鍵是實現代理對象和目標對象的同壹個接口,代理對象持有目標對象的引用。

男* * *接口代碼:

1公共接口IHello {2 /**3?*商業方法4?* @param str5?*/6 void say hello(String str);7 }

對象類別代碼:

1公共類Hello實現IHello{2?@ override 3 public void say hello(String str){ 4 system . out . println(" hello "+str);5 ?}6 7 }

代理代碼,我們給它添加日誌功能,在方法啟動前後執行特定的方法。是不是和AOP特別像?

公共類ProxyHello實現IHello{

二等兵IHello妳好;

public proxy hello(IHello hello){ super();this.hello = hello

}

@ Override public void say hello(String str){

logger . start();//添加具體方法hello . say hello(str);

logger . end();

}

}

日誌類別代碼:

1公共類記錄器{2公共靜態void start(){ 3 system . out . println(new Date()+" say hello start ... ");4 ?} 5 6 public static void end(){ 7 system . out . println(new Date()+" say hello end ");8 ?}9 }

測試代碼:

1 public class Test { 2 public static void main(String[]args){ 3 IHello Hello = new proxy Hello(new Hello());//如果我們需要日誌功能,使用代理類4//IHello Hello = new Hello();//如果我們不需要日誌功能,使用目標類5 hello . say hello(" tomorrow ");

6 ?}7 }

這樣我們實現了最簡單的AOP,但是會有壹個問題:如果我們有很多像Hello這樣的類,那麽我們是不是也要寫很多像HelloProxy這樣的類?其實也是壹件很麻煩的事情。jdk1.3之後,jdk給我們提供了壹個API?Java . lang . reflect . invocation handler的類,這個類允許我們在JVM調用壹些方法時動態地為它們做壹些事情。讓我們來實現動態代理的實現。

動態代理的實現主要是實現InvocationHandler,並將目標對象註入到代理對象中,利用反射機制執行目標對象的方法。

接口實現與靜態代理相同,代理類代碼:

1公共類DynaProxyHello實現InvocationHandler{ 2?3私人對象目標;//目標對象4 /** 5?*通過反射實例化目標對象?* @param object 7?* @return 8?*/ 9公共對象bind(Object Object){ 10 this . target = Object;11返回proxy . newproxyinstance(this . target . getclass()。getClassLoader()、this.target.getClass()。getInterfaces(),this);12 ?}13 14 ?@Override15公共對象調用(對象代理、方法方法、對象[]參數)16 Throwable { 17對象結果= null18 logger . start();//添加附加方法19 //運行目標對象的方法20Result = method。調用(這個。target,args)通過反射機制;21 ?logger . end();22返回結果;23 ?}24 25 }

測試類別代碼:

1 public class dyna test { 2 public static void main(String[]args){ 3 IHello hello =(IHello)new DynaProxyHello()。bind(new Hello());//如果我們需要日誌功能,使用代理類4//IHello Hello = new Hello();//如果我們不需要日誌功能,使用目標類5 hello . say hello(" tomorrow ");6 ?}7 }

看了上面的代碼,對比Spring AOP可能會有問題。log類只能在方法前後打印,但是AOP應該在條件滿足時執行。那麽,DynaPoxyHello對象和Logger可以解耦嗎?

看看下面的代碼實現,它將解耦DynaPoxyHello對象和記錄器:

我們需要在代理對象的方法之前或之後添加日誌操作代碼(或其他操作的代碼)。然後,我們可以抽象壹個接口,這個接口只有兩個方法:壹個是在代理對象執行方法之前執行的方法,我們稱之為start,第二個是在代理對象執行方法之後執行的方法,我們稱之為end。

記錄器的接口:

1公共接口ILogger {2 void start(Method方法);3空端(方法方法);4 }

記錄器的接口實現;

1公共類DLogger實現ILogger{ 2?@ Override 3 public void start(Method方法){ 4 system . out . println(new Date()+Method . getname()+" say hello start ... ");5 ?} 6 ?@Override 7 public void end(Method方法){ 8 system . out . println(new Date()+Method . getname()+" say hello end ");9 ?}10 }

動態代理類:

1公共類dynaproxyHello 1實現調用處理程序{ 2//調用對象3私有對象代理;4 //目標對象5私有對象目標;6 ?7公共對象綁定(對象目標,對象代理){ 8 this.target = target9 this.proxy = proxy10返回proxy . newproxyinstance(this . target . getclass()。getClassLoader()、this.target.getClass()。getInterfaces(),this);11 ?}12 13 14 ?@Override15公共對象調用(對象代理、方法方法、對象[]參數)16 Throwable { 17對象結果= null18 //反映操作員實例19 class clazz = this . proxy . getclass();20 //反射得到操作符的開始方法21方法開始= clazz。getdeclaredmethod ("start ",新類[] {method。class });22 //反射執行啟動方法23 start.invoke (this.proxy,new object[]{ this . proxy . getclass()});24 //執行原方法25方法。調用(這個。要處理的對象的target,args);26 //反射得到運算符的結束方法27 methodend = clazz。getdeclaredmethod ("end ",新類[] {method。class });28 //反射執行結束方法29 end.invoke (this.proxy,new object[]{ method });30返回結果;31 ?}32 33 }

測試代碼:

1公共類DynaTest1 {2公共靜態void main(String[]args){ 3 IHello hello =(IHello)新的DynaProxyHello1()。bind(new Hello()、new DLogger());//如果我們需要日誌功能,使用代理類4//IHello Hello = new Hello();//如果我們不需要日誌功能,使用目標類5 hello . say hello(" tomorrow ");6 ?}7 }

通過上面的例子,我們可以發現AOP的功能已經通過動態代理和啟動技術基本實現了。如果我們只需要在方法執行前打印日誌,就不需要實現end()方法,這樣就可以控制打印時間。如果想要指定的方法打印日誌,只需要在invoke()方法中添加壹個對方法名稱的判斷,方法名稱就可以寫入xml文件中,這樣就可以實現與配置文件的解耦,從而實現壹個簡單的spring aop框架。

  • 上一篇:自考生能考工程師嗎
  • 下一篇:非均勻有理B樣條的源代碼 最好用MATLAB做 誰知道啊 急用
  • copyright 2024編程學習大全網