----------------------ASP.Net+Android+IOS開發.Net培訓、期待與您交流! --------
黑馬程序員_java高級篇代理Day14(上)
#類加載器#
類加載器也是一個java類,它將別的java類加載進來.
顯然第一個不是java類的,我們可以將它加載進來.BootStrap
這個類的工作是啥尼,
System.out.println(System.class.getClassLoader());
輸出的是null,說明加載System這個類的並不存在一個類,他其實就是我們所說的BootStrap.
Java虛擬機給我們提供了三個類加載器, BootStrap,ExtClassloader,AppClassLoader 這些類加載器是父子關係,組成樹狀結構.
#類加載器的委託機制#
Java虛擬機要加載一個類時,到底要派出哪個類去加載
Java虛擬機會派當前線程的類去加載第一個類
如果類A引用了類B,java虛擬機將用加載類A的加載器去加載類B。
我們也可以寫代碼指定某個類加載器去加載。
對於我們是否可以寫一個java.lang.System,其實寫了也是白寫,由於加載器的機制問題
,爲了讓內存中只存在一份字節碼,所以我們開始時問祖宗.BootStrap,你裏面有這個字節碼?對於我們的System,是在rt包中的,所以我們寫了也不會調用。
如果你硬是要寫一個,那我們自己可以寫一個類加載器去加載。
#寫自己的類加載器#
我們寫的類加載器必須繼承一個類加載器ClassLoader
我們要實現的是findclass,如:
Void findclass()
{
LoadClass(“name”);
DefineClass();
}
#一個類加載問題的高級分析#
這個要涉及到的知識,web項目中的Servlet
當我們在doget方法中加入
ClassLoader loader=this.getClass().getClassLoader();
while(loader!=null)
{
System.out.println(loader.getClass().getName());
loader=loader.getParent();
}
我們來看看Tomcat調用的類加載器。
我們注意到Servlet1 extends HttpServlet,我們定義的Servlet繼承HttpServlet,Servlet使用的類加載器是ExtClassLoader,但是我們要知道如果Servlet用ExtClassLoader加載,HttpServlet同樣也用ExtClassLoader加載,當我們在ExtClassLoader的父類加載器中不能加載這個類時,我們會用ExtClassLoader,但是ExtClassLoader也不能加載,就會出錯。
代理的概念與作用
通過代理,我們可以從中得到方便,Clent本來是調用Tatget的,但是當我們有了代理後,client就直接調用Proxy,代理也實現了接口中的方法,我們可以在配置文件中,直接配置是用代理還是目標
#AOP#
面向方面的編程
當我們寫幾個類的時候,Student類增刪改查,cou類的增刪改查,這裏面都會涉及到安全,日誌,爲了解決這個問題,我們會用到代理技術。
#動態代理技術#
JVM可以在運行期間動態的生成類的字節碼,這種動態生成的類往往叫做動態代理類。
但是當我們的目標方法沒有實現接口,我們的代理類就不能說用接口實現所有相同的方法了
,但是出現了CGLib類可以幫我們生成一個類的子類。
我們用代理方法,可添加一些代碼。
JDK中具體的動態代理類是怎麼產生的呢?
1.產生代理類$Proxy0類
執行了Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
將產生$Proxy0類,它繼承Proxy對象,並根據第二個參數,實現了被代理類的所有接口,自然就可以生成接口要實現的所有方法了(這時候會重寫hashcode,toString和equals三個方法),但是還沒有具體的實現體;
2. 將代理類$Proxy0類加載到JVM中
這時候是根據Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第一個參數----就是被代理類的類加載器,把當前的代理類加載到JVM中
3. 創建代理類$Proxy0類的對象
調用的$Proxy0類的$Proxy0(InvocationHandler)構造函數,生成$Proxy0類的對象
參數就是Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第三個參數
這個參數就是我們自己實現的InvocationHandler對象,我們知道InvocationHandler對象中組合加入了代理類代理的接口類的實現類;所以,$Proxy0對象調用所有要實現的接口的方法,都會調用InvocationHandler對象的invoke()方法實現;
4. 生成代理類的class byte
動態代理生成的都是二進制class字節碼
----------------------ASP.Net+Android+IOS開發.Net培訓、期待與您交流! --------