㈠ Spring的兩種動態代理有什麼區別
JAVA 代理實現
代理的實現分動態代理和靜態代理,靜態代理的實現是對已經生成了的JAVA類進行封裝。
動態代理則是在運行時生成了相關代理累,在JAVA中生成動態代理一般有兩種方式。
㈡ Java中動態代理是什麼意思
舉個例子吧,比如說你暗戀一個小美女,你給她寫了個情書,你不好意思直接給她,就讓我轉給她。
我也暗戀這個小美女,我收到你的情書以後,我送你的情書之前跟小美女說你這個人人品差長得丑還沒錢,然後再把你的情書給她。
動態代理就是這個過程。本來是你和小美女之間的關系,但中間讓我轉達一下,我在轉達的前後可以干一些自己的事情。更具體的說,就是A調用B,但不直接調用,A通過調用C,C再調用B,C在調用B的前後可以做一些自己的事情,比如說打日誌、許可權驗證等,這樣就把業務代碼與系統代碼分開,同時減少了A和B之間的耦合。
動態代理的經典應用是Spring AOP。有興趣可以學學。
㈢ Spring框架的動態代理是干什麼用的
spring的動態代理實現有兩種,一種第三方,一種是JDK的反射。
動態代理可以快速地實現工廠生成對象實例注入業務中使用到的實例。
㈣ java動態代理是什麼
import java.lang.reflect.Proxy;
A. 創建一個實現介面InvocationHandler的類,他必須實現invoke方法
B. 創建被代理的類以及介面。
C. 通過Proxy的靜態方法newProxyInstance(ClassLoader loader,Class【】interfaces,InvocationHandler handler)創建一個代理
D. 通過代理調用方法。
java動態代理:是在運行是生成的class對象,在生成時必須提供一組或一個interface給它,然後該class就宣稱它實現了這些interface。你當然可以把該class的實例當做這些interface中的任何一個來用,當然,這個DynamicProxy其實就是一個Proxy,他不會替你做實質性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。因此,DynamicProxy必須實現InvocationHandler介面。
5) 一個動態代理了和一個InvocationHandler 實現關聯的。每一個動態代理實例的調用都要通過InvocationHandler介面的handler(調用處理器)來調用,動態代理不做任何執行操作,只是在創建動態代理時,把要實現的介面和handler關聯,動態代理要幫助被代理執行的任務,要轉交給handler來執行。其實就是調用invoke方法。
㈤ java動態代理有什麼作用
作用非常大,在很多底層框架中都會用得到,比如struts,Spring等都用到了動態代理,它的作用很簡單,就是將你要使用的類,重新生成一個子類或本類,這樣框架就可以利用這個新生成的類做一些事情,比如在該類的方法前後加一些代碼。。
這樣的話,你想像一下,你是不是不用修改任何已經編寫好的代碼,只要使用代理就可以靈活的加入任何東西,將來不喜歡了,不用也不會影響原來的代碼。
㈥ java 動態代理有什麼作用有什麼優點解決了什麼問題不要用程序來說,就直接用語言描述。謝謝了
簡單來說可以隱藏實現,比如將你與A的交互通過代理將實現轉變為與B的交互,其中關鍵一點是如果在實現中保留一個對自己的對象的引用的話,就可以達到動態增強代理類功能的目的。
㈦ 什麼是反射技術什麼是靜態代理什麼是動態代理什麼是aop
JAVA的靜態代理與動態代理比較 一、概念 代理模式是常用的Java 設計模式,它的特徵是代理類與委託類有同樣的介面,代理類主要負責為委託類預處理消息、過濾消息、把消息轉發給委託類,以及事後處理消息等。代理類與委託類之間通常會存在關聯關系,一個代理類的對象與一個委託類的對象關聯,代理類的對象本身並不真正實現服務,而是通過調用委託類的對象的相關方法,來提供特定的服務。按照代理類的創建時期,代理類可分為兩種。 靜態代理類: 由程序員創建或由特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。動態代理類:在程序運行時,運用反射機制動態創建而成。 二、靜態代理類 如下, HelloServiceProxy 類是代理類,HelloServiceImpl類是委託類,這兩個類都實現了HelloService介面。其中HelloServiceImpl類是HelloService介面的真正實現者,而HelloServiceProxy類是通過調用HelloServiceImpl 類的相關方法來提供特定服務的。HelloServiceProxy類的echo()方法和getTime()方法會分別調用被代理的HelloServiceImpl 對象的echo()方法和getTime()方法,並且在方法調用前後都會執行一些簡單的列印操作。 由此可見,代理類可以為委託類預處理消息、把消息轉發給委託類和事後處理消息等。 常式1 HelloService.java package proxy; import java.util.Date; public interface HelloService{ public String echo(String msg); public Date getTime(); } 常式2 HelloServiceImpl.java package proxy; import java.util.Date; public class HelloServiceImpl implements HelloService{ public String echo(String msg){ return "echo:"+msg; } public Date getTime(){ return new Date(); } } 常式3 HelloServiceProxy.java package proxy; import java.util.Date; public class HelloServiceProxy implements HelloService{ private HelloService helloService; //表示被代理的HelloService 實例 public HelloServiceProxy(HelloService helloService){ this.helloService=helloService; } public void setHelloServiceProxy(HelloService helloService){ this.helloService=helloService; } public String echo(String msg){ System.out.println("before calling echo()"); //預處理 String result=helloService.echo(msg); //調用被代理的HelloService 實例的echo()方法 System.out.println("after calling echo()"); //事後處理 return result; } public Date getTime(){ System.out.println("before calling getTime()"); //預處理 Date date=helloService.getTime(); //調用被代理的HelloService 實例的getTime()方法 System.out.println("after calling getTime()"); //事後處理 return date; } } 在Client1 類的main()方法中,先創建了一個HelloServiceImpl對象,又創建了一個HelloServiceProxy對象,最後調用HelloServiceProxy對象的echo()方法。 常式4 Client1.java package proxy; public class Client1{ public static void main(String args[]){ HelloService helloService=new HelloServiceImpl(); HelloService helloServiceProxy=new HelloServiceProxy(helloService); System.out.println(helloServiceProxy.echo("hello")); } } 運行Client1 類,列印結果如下: before calling echo() after calling echo() echo:hello 常式3 的HelloServiceProxy 類的源代碼是由程序員編寫的,在程序運行前,它的.class文件就已經存在了,這種代理類稱為靜態代理類。 三、動態代理類 與靜態代理類對照的是動態代理類,動態代理類的位元組碼在程序運行時由Java反射機制動態生成,無需程序員手工編寫它的源代碼。動態代理類不僅簡化了編程工作,而且提高了軟體系統的可擴展性,因為Java 反射機制可以生成任意類型的動態代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 介面提供了生成動態代理類的能力。 Proxy類提供了創建動態代理類及其實例的靜態方法。 (1)getProxyClass()靜態方法負責創建動態代理類,它的完整定義如下: public static Class<?> getProxyClass(ClassLoader loader, Class<?>[] interfaces) throws IllegalArgumentException 參數loader 指定動態代理類的類載入器,參數interfaces 指定動態代理類需要實現的所有介面。 (2)newProxyInstance()靜態方法負責創建動態代理類的實例,它的完整定義如下: public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) throws IllegalArgumentException 參數loader 指定動態代理類的類載入器,參數interfaces 指定動態代理類需要實現的所有介面,參數handler 指定與動態代理類關聯的 InvocationHandler 對象。 以下兩種方式都創建了實現Foo介面的動態代理類的實例: /**** 方式一 ****/ //創建InvocationHandler對象 InvocationHandler handler = new MyInvocationHandler(...); //創建動態代理類 Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class }); //創建動態代理類的實例 Foo foo = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler }); /**** 方式二 ****/ //創建InvocationHandler對象 InvocationHandler handler = new MyInvocationHandler(...); //直接創建動態代理類的實例 Foo foo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class }, handler); 由Proxy類的靜態方法創建的動態代理類具有以下特點: 動態代理類是public、final和非抽象類型的; 動態代理類繼承了java.lang.reflect.Proxy類; 動態代理類的名字以「$Proxy」開頭; 動態代理類實現getProxyClass()和newProxyInstance()方法中參數interfaces指定的所有介面; Proxy 類的isProxyClass(Class<?> cl)靜態方法可用來判斷參數指定的類是否為動態代理類。只有通過Proxy類創建的類才是動態代理類; 動態代理類都具有一個public 類型的構造方法,該構造方法有一個InvocationHandler 類型的參數。 由Proxy類的靜態方法創建的動態代理類的實例具有以下特點: 1. 假定變數foo 是一個動態代理類的實例,並且這個動態代理類實現了Foo 介面,那麼「foo instanceof Foo」的值為true。把變數foo強制轉換為Foo類型是合法的: (Foo) foo //合法 2.每個動態代理類實例都和一個InvocationHandler 實例關聯。Proxy 類的getInvocationHandler(Object proxy)靜態方法返回與參數proxy指定的代理類實例所關聯的InvocationHandler 對象。 3.假定Foo介面有一個amethod()方法,那麼當程序調用動態代理類實例foo的amethod()方法時,該方法會調用與它關聯的InvocationHandler 對象的invoke()方法。 InvocationHandler 介面為方法調用介面,它聲明了負責調用任意一個方法的invoke()方法: Object invoke(Object proxy,Method method,Object[] args) throws Throwable 參數proxy指定動態代理類實例,參數method指定被調用的方法,參數args 指定向被調用方法傳遞的參數,invoke()方法的返回值表示被調用方法的返回值。 四、最後看一個實例: HelloServiceProxyFactory 類的getHelloServiceProxy()靜態方法負責創建實現了HelloService介面的動態代理類的實例。 常式5 HelloServiceProxyFactory.java package proxy; import java.lang.reflect.*; public class HelloServiceProxyFactory { /** 創建一個實現了HelloService 介面的動態代理類的實例 * 參數helloService 引用被代理的HelloService 實例 */ public static HelloService getHelloServiceProxy(final HelloService helloService){ //創建一個實現了InvocationHandler介面的匿名類的實例 InvocationHandler handler=new InvocationHandler(){ public Object invoke(Object proxy,Method method,Object args[])throws Exception{ System.out.println("before calling "+method); //預處理 Object result=method.invoke(helloService,args); //調用被代理的HelloService 實例的方法 System.out.println("after calling "+method); //事後處理 return result; } }; Class classType=HelloService.class; return (HelloService)Proxy.newProxyInstance(classType.getClassLoader(), new Class[]{classType}, handler); } } 如下所示的Client2 類先創建了一個HelloServiceImpl 實例,然後創建了一個動態代理類實例helloServiceProxy,最後調用動態代理類實例的echo()方法。 常式6 Client2.java package proxy; public class Client2{ public static void main(String args[]){ HelloService helloService=new HelloServiceImpl(); HelloService helloServiceProxy=HelloServiceProxyFactory.getHelloServiceProxy(helloService); System.out.println("動態代理類的名字為"+helloServiceProxy.getClass().getName()); System.out.println(helloServiceProxy.echo("Hello")); } } 運行Client2,列印結果如下: 動態代理類的名字為$Proxy0 before calling public abstract java.lang.String proxy.HelloService.echo(java.lang.String) after calling public abstract java.lang.String proxy.HelloService.echo(java.lang.String) echo:Hello 從結果看出,動態代理類的名字為$Proxy0。