java基礎(七)網絡編程/反射/動態代理

這輩子沒辦法作太多事情,因此每一件都要作到精彩絕倫!java

People can't do too many things in my life,so everything will be wonderful   算法

 

本資料只進行簡單介紹說明以及相關重要問題的解答;關於類的詳細說明及使用請參考java API文檔編程

本文參考的依據是:JDK API 1.6.0 中文版,免費下載地址:http://down.51cto.com/data/2300228設計模式

1.     網絡編程

l  計算機網絡數組

                   是指將地理位置不一樣的具備獨立功能的多臺計算機及其外部設備,經過通訊線路鏈接起來,在網絡操做系統,網絡管理軟件及網絡通訊協議的管理和協調下,實現資源共享和信息傳遞的計算機系統。服務器

l  網絡編程網絡

                   就是用來實現網絡互連的不一樣計算機上運行的程序間能夠進行數據交換。多線程

1.1     網絡模型

l  計算機網絡之間以何種規則進行通訊,就是網絡模型研究問題。jvm

l  網絡模型通常是指socket

                   OSIOpen SystemInterconnection開放系統互連)參考模型

                   TCP/IP參考模型

wKioL1j1fRfSUpdwAAEDq5Uk_QM511.png

網絡模型7層概述:

1.物理層:主要定義物理設備標準,如網線的接口類型、光纖的接口類型、各類傳輸介質的傳輸速率等。它的主要做用是傳輸比特流(就是由10轉化爲電流強弱來進行傳輸,到達目的地後在轉化爲10,也就是咱們常說的數模轉換與模數轉換)。這一層的數據叫作比特。

2. 數據鏈路層:主要將從物理層接收的數據進行MAC地址(網卡的地址)的封裝與解封裝。常把這一層的數據叫作幀。在這一層工做的設備是交換機,數據經過交換機來傳輸。

3. 網絡層:主要將從下層接收到的數據進行IP地址(例192.168.0.1)的封裝與解封裝。在這一層工做的設備是路由器,常把這一層的數據叫作數據包。

4. 傳輸層:定義了一些傳輸數據的協議和端口號(WWW端口80等),如:TCP(傳輸控制協議,傳輸效率低,可靠性強,用於傳輸可靠性要求高,數據量大的數據),UDP(用戶數據報協議,與TCP特性偏偏相反,用於傳輸可靠性要求不高,數據量小的數據,如QQ聊天數據就是經過這種方式傳輸的)。主要是將從下層接收的數據進行分段和傳輸,到達目的地址後再進行重組。經常把這一層數據叫作段。

5.會話層:經過傳輸層(端口號:傳輸端口與接收端口)創建數據傳輸的通路。主要在你的系統之間發起會話或者接受會話請求(設備之間須要互相認識能夠是IP也能夠是MAC或者是主機名)

6.表示層:主要是進行對接收的數據進行解釋、加密與解密、壓縮與解壓縮等(也就是把計算機可以識別的東西轉換成人可以能識別的東西(如圖片、聲音等)。

7.應用層: 主要是一些終端的應用,好比說FTP(各類文件下載),WEBIE瀏覽),QQ之類的(能夠把它理解成咱們在電腦屏幕上能夠看到的東西.就是終端應用)。

wKiom1j1fSKBzcNZAABYkEAWRfc398.png

1.2     網絡通訊三要素

網絡模型說完了,咱們要進行通信,須要哪些要素呢?

好比說:我要跟你說話.

第一個條件:我要先找到你 (IP)

第二個條件:你得有接收數據的地方  耳朵 (端口)

第三個條件:我跟你說話,你能接收到,咱按什麼方式接收啊,我說英文你懂嗎,說韓文你懂嗎,不懂是吧,因此我仍是說中文把.(協議)

1.2.1       IP地址

l  IP地址:InetAddress網絡中設備的標識,不易記憶,可用主機名!

要想讓網絡中的計算機可以互相通訊,必須爲每臺計算機指定一個標識號,經過這個標識號來指定要接受數據的計算機和識別發送的計算機,在TCP/IP協議中,這個標識號就是IP地址。

  • 所謂IP地址就是給每一個鏈接在Internet上的主機分配的一個32bit地址。按照TCP/IP規定,IP地址用二進制來表示,每一個IP地址長32bit,比特換算成字節,就是4個字節。例如一個採用二進制形式的IP地址是「00001010000000000000000000000001」,這麼長的地址,人們處理起來也太費勁了。爲了方便人們的使用,IP地址常常被寫成十進制的形式,中間使用符號「.」分開不一樣的字節。因而,上面的IP地址能夠表示爲「10.0.0.1」IP地址的這種表示法叫作「點分十進制表示法」,這顯然比10容易記憶得多。

 

1.2.2       端口號

         用於標識進程的邏輯地址,不一樣進程的標識

l  物理端口 網卡口

l  邏輯端口 咱們指的就是邏輯端口

         A:每一個網絡程序都會至少有一個邏輯端口

         B:用於標識進程的邏輯地址,不一樣進程的標識

         C:有效端口:0~65535,其中0~1024系統使用或保留端口。

         經過360能夠查看端口號

 

1.2.3       傳輸協議

         通信的規則

         常見協議:TCPUDP

l  UDP

                   將數據源和目的封裝成數據包中,不須要創建鏈接;每一個數據報的大小在限制在64k;因無鏈接,是不可靠協議;不須要創建鏈接,速度快

l  TCP

                   創建鏈接,造成傳輸數據的通道;在鏈接中進行大數據量傳輸;經過三次握手完成鏈接,是可靠協議;必須創建鏈接,效率會稍低

1.3     Socket

Socket套接字:

網絡上具備惟一標識的IP地址和端口號組合在一塊兒才能構成惟一能識別的標識符套接字。

Socket原理機制:

通訊的兩端都有Socket

網絡通訊其實就是Socket間的通訊。

數據在兩個Socket間經過IO傳輸。

wKiom1j1fQSDwNG2AABYkEAWRfc496.png

 

1.3.1       UDP傳輸

DatagramSocketDatagramPacket

創建發送端,接收端。

創建數據包。

調用Socket的發送接收方法。

關閉Socket

發送端與接收端是兩個獨立的運行程序。

  • 發送端思路:

  • 1:創建udpsocket服務

  • 2:將要發送的數據封裝成數據包

  • 3:經過udpsocket服務,將數據包發送出

  • 4:關閉資源

代碼:DatagramSocket ds=new DatagramSocket();//"127.0.0.1",10086

                            byte[]bys="hello world".getBytes();

                            DatagramPacketdp=new DatagramPacket(bys,bys.length,InetAddress.getByName("127.0.0.1"),10086);

                            ds.send(dp);

                            ds.close();

  • 接收端思路

1:創建udpsocket服務.

2:經過receive方法接收數據

3:將收到的數據存儲到數據包對象中

4:經過數據包對象的功能來完成對接收到數據進行解析.

5:能夠對資源進行關閉

代碼:DatagramSocket ds=new DatagramSocket(10086);

                            byte[]bys=new byte[1024];

                            DatagramPacketdp=new DatagramPacket(bys,bys.length);

                            ds.receive(dp);

 

                            InetAddressaddress=InetAddress.getByName();

                            Stringip=address.getHostAddress();

                            Stringstr=new String(dp.getData(),0,dp.getLength());

                            System.out.println(ip+"--"+str);

                            //ds.close();//dp.close();

1.3.2       TCP傳輸

SocketServerSocket

創建客戶端和服務器端

創建鏈接後,經過Socket中的IO流進行數據的傳輸

關閉socket

一樣,客戶端與服務器端是兩個獨立的應用程序。

  • 客戶端:

1:創建客戶端的Socket服務,並明確要鏈接的服務器。

2:若是鏈接創建成功,就代表,已經創建了數據傳輸的通道.就能夠在該通道經過IO進行數據的讀取和寫入.該通道稱爲Socket,Socket流中既有讀取流,也有寫入流.

3:經過Socket對象的方法,能夠獲取這兩個流

4:經過流的對象能夠對數據進行傳輸

5:若是傳輸數據完畢,關閉資源

代碼:     Socket s=newSocket("127.0.0.1",10010);

                            BufferedOutputStreambos=new BufferedOutputStream(s.getOutputStream());

                            bos.writer("helloworld".getBytes());

                            s.close();

  • 服務(接收)端

1:創建服務器端的socket服務,須要一個端口

2:服務端沒有直接流的操做,而是經過accept方法獲取客戶端對象,在經過獲取到的客戶端對象的流和客戶端進行通訊

3:經過客戶端的獲取流對象的方法,讀取數據或者寫入數據

4:若是服務完成,須要關閉客戶端,而後關閉服務器,可是,通常會關閉客戶端,不會關閉服務器,由於服務端是一直提供服務的

代碼:     ServerSocket ss=newServerSocket(10010);

                            Sockets=ss.accept();

                            BufferedInputStreambis=new BufferedInputstream(s.getInputStream());

 

                            Stringip=s.getInetAddress().getHostAddress();

                            byte[]bys=new byte[1024];

                            intlen=0;

                            while((len=bis.read(bys))!=-1){

                                     System.out.println(newString(bys,0,len));

                            }

                            s.close();

wKioL1j1fJOA4Gs_AACHl6FEVbE834.png

1.3.3       TCP傳輸容易出現的問題

l  客戶端鏈接上服務端,兩端都在等待,沒有任何數據傳輸。

l  經過例程分析:

         由於read方法或者readLine方法是阻塞式。

l  解決辦法:

         自定義結束標記

         使用shutdownInputshutdownOutput方法。

 

2.     類的加載

類的加載

當程序要使用某個類時,若是該類還未被加載到內存中,則系統會經過加載,鏈接,初始化三步來實現對這個類進行初始化。

加載

就是指將class文件讀入內存,併爲之建立一個Class對象。

任何類被使用時系統都會創建一個Class對象。

鏈接

驗證 是否有正確的內部結構,並和其餘類協調一致

準備 負責爲類的靜態成員分配內存,並設置默認初始化值

解析 將類的二進制數據中的符號引用替換爲直接引用

初始化 就是咱們之前講過的初始化步驟

2.1     類初始化時機

建立類的實例

訪問類的靜態變量,或者爲靜態變量賦值

調用類的靜態方法

使用反射方式來強制建立某個類或接口對應的java.lang.Class對象

初始化某個類的子類

直接使用java.exe命令來運行某個主類

2.2     類加載器

類加載器

負責將.class文件加載到內存中,併爲之生成對應的Class對象。

雖然咱們不須要關心類加載機制,可是瞭解這個機制咱們就能更好的理解程序的運行。

類加載器的組成

BootstrapClassLoader 根類加載器

l 也被稱爲引導類加載器,負責Java核心類的加載

l 好比System,String等。在JDKJRElib目錄下rt.jar文件中

ExtensionClassLoader 擴展類加載器

l 負責JRE的擴展目錄中jar包的加載。

l JDKJRElib目錄下ext目錄

SysetmClassLoader 系統類加載器

l 負責在JVM啓動時加載來自java命令的class文件,以及classpath環境變量所指定的jar包和類路徑

3.     反射

JAVA反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。

要想解剖一個類,必須先要獲取到該類的字節碼文件對象。而解剖使用的就是Class類中的方法.因此先要獲取到每個字節碼文件對應的Class類型的對象.

3.1     三種獲取Class對象的方式

1:Person p = new Person();

 Class c = p.getClass();

2:Class c2 = Person.class;

  任意數據類型都具有一個class靜態屬性,看上去要比第一種方式簡單.

3:將類名做爲字符串傳遞給Class類中的靜態方法forName便可

 Class c3 = Class.forName("Person");

        

第三種和前兩種的區別                  

前兩種你必須明確Person類型.

後面是你我這種類型的字符串就行.這種擴展更強.我不須要知道你的類.我只提供字符串,按照配置文件加載就能夠了!

3.2     獲取構造方法並使用

l  獲取構造方法

                   getConstructors

                   getDeclaredConstructors

l  建立對象

                   newInstance()

                   con.newInstance(zhangsan",20);

3.3     獲取成員變量並使用

l  獲取全部成員

                   getFields,getDeclaredFields

l  獲取單個成員

                   getField,getDeclaredField

l  修改爲員的值

                   set(Objectobj,Object value)
   將指定對象變量上此 Field 對象表示的字段設置爲指定的新值。

3.4     獲取成員方法

l  獲取全部方法

                   getMethods

                   getDeclaredMethods

l  獲取單個方法

                   getMethod

                   getDeclaredMethod

暴力訪問

                   method.setAccessible(true);

 

4.     動態代理

動態代理

代理:原本應該本身作的事情,卻請了別人來作,被請的人就是代理對象。

舉例:春季回家買票讓人代買

動態代理:在程序運行過程當中產生的這個對象

而程序運行過程當中產生對象其實就是咱們剛纔反射講解的內容,因此,動態代理其實就是經過反射來生成一個代理

 

  • Javajava.lang.reflect包下提供了一個Proxy類和一個InvocationHandler接口,經過使用這個類和接口就能夠生成動態代理對象。JDK提供的代理只能針對接口作代理。動態代理:cglib

  • Proxy類中的方法建立動態代理對象

  • public static Object newProxyInstance(ClassLoaderloader,Class<?>[] interfaces,InvocationHandler h)

  • 最終會調用InvocationHandler的方法

  • InvocationHandler

  • Object invoke(Object proxy,Method method,Object[] args)

Proxy類中建立動態代理對象的方法的三個參數;

ClassLoader對象,定義了由哪一個ClassLoader對象來對生成的代理對象進行加載

Interface對象的數組,表示的是我將要給我須要代理的對象提供一組什麼接口,若是我提供了一組接口給它,那麼這個代理對象就宣稱實現了該接口(多態),這樣我就能調用這組接口中的方法了

InvocationHandler對象,表示的是當我這個動態代理對象在調用方法的時候,會關聯到哪個InvocationHandler對象上

 

每個動態代理類都必需要實現InvocationHandler這個接口,而且每一個代理類的實例都關聯到了一個handler,當咱們經過代理對象調用一個方法的時候,這個方法的調用就會被轉發爲由InvocationHandler這個接口的invoke 方法來進行調用。

 

InvocationHandler接口中invoke方法的三個參數:

proxy:表明動態代理對象

method:表明正在執行的方法

args:表明調用目標方法時傳入的實參

 

Proxy.newProxyInstancedebug查看

建立的代理對象是在jvm運行時動態生成的一個對象,它並非咱們的InvocationHandler類型,

也不是咱們定義的那組接口的類型,而是在運行時動態生成的一個對象,而且命名方式都是這樣的形式,

$開頭,proxy爲中,最後一個數字表示對象的標號。

System.out.println(u.getClass().getName());

java基礎系列:

java基礎(一)java語法

java基礎(二)面向對象

java基礎(三)繼承/多態/接口

java基礎(四)經常使用類/算法

java基礎(五)集合/IO流/異常

java基礎(六)多線程/設計模式

java基礎(七)網絡編程/反射/動態代理