Java學習路線-32:ClassLoader類加載器反射與代理設計模式

      網友投稿 769 2022-05-29

      第25 章 : ClassLoader類加載器

      115 ClassLoader類加載器簡介

      系統環境變量 CLASSPATH

      JVM -> ClassLoader -> CLASSPATH -> .class

      1

      加載器,由上至下執行

      Bootstrap 系統類加載器 PlatformClassLoader 平臺類加載器 AppClassLoader 應用程序加載器 自定義類加載器(磁盤、網絡)

      1

      2

      3

      4

      5

      6

      7

      系統類加載器都是根據CLASSPATH路徑查找類加載

      應用場景:

      客戶端動態更新服務器端的代碼

      Java類加載器:雙親加載機制

      為了保證系統安全性,開發者自定義類與系統類重名,不會被加載

      /demo/Person.java

      public class Person { public void sayHello(){ System.out.println("hello"); } }

      1

      2

      3

      4

      5

      6

      MyClassLoader.java

      import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; class MyClassLoader extends ClassLoader { private static final String PERSON_CLASS_PATH = "/demo" + File.separator + "Person.class"; public Class loadMyClass(String className) throws IOException { byte[] data = this.loadClassData(); if (data != null) { return super.defineClass(className, data, 0, data.length); } return null; } public byte[] loadClassData() throws IOException { InputStream input = null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); // 將數據加載到內存 byte[] data = null; byte[] temp = new byte[1024]; int len = 0; try { input = new FileInputStream(PERSON_CLASS_PATH); while ((len = input.read(temp)) != -1) { bos.write(temp, 0, len); } // 讀取所有的字節 data = bos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { if (input != null) { input.close(); } if (bos != null) { bos.close(); } } return data; } } class Demo { public static void main(String[] args) throws Exception{ MyClassLoader loader = new MyClassLoader(); Class cls = loader.loadMyClass("Person"); Object obj = cls.getDeclaredConstructor().newInstance(); Method method = cls.getDeclaredMethod("sayHello"); method.invoke(obj); // hello } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      第26 章 : 反射與代理設計模式

      117 靜態代理設計模式

      傳統代理設計

      必須有接口

      標準的代理設計

      // 接口標準 interface IMessage { void send(); } // 業務實現類 class MessageImpl implements IMessage { @Override public void send() { System.out.println("發送"); } } // 代理類 class MessageProxy implements IMessage { private IMessage message; public MessageProxy(IMessage message) { this.message = message; } @Override public void send() { if (this.isConnect()) { this.message.send(); } } public void close() { } public boolean isConnect() { return true; } } class Demo { public static void main(String[] args) { IMessage message = new MessageProxy(new MessageImpl()); message.send(); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      Java學習路線-32:ClassLoader類加載器反射與代理設計模式

      42

      43

      44

      45

      客戶端和接口子類產生了耦合

      最好引入工廠設計模式進行代理對象獲取

      靜態代理類:

      一個代理類只為一個接口服務

      118 動態代理設計模式

      最好的做法是為所有功能一致的業務操作接口提供統一的代理處理操作

      不管是動態代理類還是靜態代理類都一定要接收真實業務實現子類對象

      代碼實現

      import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 接口標準 interface IMessage { void send(); } // 業務實現類 class MessageImpl implements IMessage { @Override public void send() { System.out.println("發送"); } } // 動態代理類 class MyProxy implements InvocationHandler{ private Object target; // 保存真實業務對象 // 真實業務對象與代理業務對象之間的綁定 public Object bind(Object target){ this.target = target; Class cls = target.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; if (this.isConnect()) { obj = method.invoke(this.target, args); this.close(); } return obj; } public void close() { } public boolean isConnect() { return true; } } class Demo { public static void main(String[] args) { IMessage message =(IMessage)new MyProxy().bind(new MessageImpl()); message.send(); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      119 CGLIB實現代理設計模式

      如果要實現代理設計模式,那么一定是基于接口的應用

      CGLIB開發包實現基于類的代理設計模式

      Code Generation Library

      pom.xml 引入

      cglib cglib 2.2.2

      1

      2

      3

      4

      5

      6

      7

      代碼實現

      import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; // 業務實現類 class Message { public void send() { System.out.println("發送"); } } // 動態代理類 class MyProxy implements MethodInterceptor { private Object target; // 保存真實業務對象 // 真實業務對象與代理業務對象之間的綁定 public MyProxy(Object target) { this.target = target; } @Override public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object obj = null; if (this.isConnect()) { obj = method.invoke(this.target, args); this.close(); } return obj; } public void close() { } public boolean isConnect() { return true; } } class Demo { public static void main(String[] args) { Message message = new Message(); // 真實主體 Enhancer enhancer = new Enhancer(); // 負責代理操作的程序類 enhancer.setSuperclass(message.getClass()); // 假定一個父類 enhancer.setCallback(new MyProxy(message)); Message proxyMessage = (Message) enhancer.create(); proxyMessage.send(); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      建議:基于接口的設計比較合理

      Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Spark Core快速入門系列(8) | RDD 的持久化
      下一篇:Minima黑色響應式后臺管理模板
      相關文章
      亚洲av无码精品网站| 久久精品亚洲男人的天堂| 久久亚洲精品无码播放| 亚洲精品乱码久久久久蜜桃| 77777亚洲午夜久久多喷| 亚洲人成电影院在线观看| 亚洲视频在线观看视频| 精品亚洲麻豆1区2区3区| 亚洲一区二区三区四区在线观看 | 亚洲精品9999久久久久无码| 一区二区亚洲精品精华液| 日韩亚洲产在线观看| 亚洲kkk4444在线观看| 亚洲成年网站在线观看| 亚洲色www永久网站| 亚洲精品乱码久久久久蜜桃| 亚洲爆乳精品无码一区二区| 日韩欧美亚洲中文乱码| 国产亚洲精品国产福利在线观看| 无码欧精品亚洲日韩一区夜夜嗨 | 亚洲性日韩精品国产一区二区| 亚洲国产专区一区| 国产亚洲色婷婷久久99精品91| 在线精品亚洲一区二区小说| 亚洲精品无码mv在线观看网站| 亚洲91av视频| 亚洲成在人线电影天堂色| 亚洲中文字幕一二三四区苍井空 | 亚洲大尺度无码专区尤物| 国产aⅴ无码专区亚洲av| 久久亚洲成a人片| 日韩亚洲Av人人夜夜澡人人爽| 亚洲精品国产电影午夜| 亚洲香蕉在线观看| 亚洲另类无码专区首页| 亚洲成a人一区二区三区| 亚洲无码在线播放| 久久亚洲美女精品国产精品 | 亚洲中文字幕无码久久精品1| 亚洲成Av人片乱码色午夜| 91亚洲一区二区在线观看不卡|