Java学习路线-32:ClassLoader类加载器反射与代理设计模式

网友投稿 684 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

Java学习路线-32:ClassLoader类加载器反射与代理设计模式

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

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黑色响应式后台管理模板
相关文章