本笔记来源于:尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备)
b站视频
1.代理模式的原理:
使用一个代理将对象包装起来, 然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
2.静态代理
2.1 举例:
实现Runnable接口的方法创建多线程。
1 2 3 4 5 6 7
| Class MyThread implements Runnable{} Class Thread implements Runnable{} main(){ MyThread t = new MyThread(); Thread thread = new Thread(t); thread.start(); }
|
2.2 静态代理的缺点:
① 代理类和目标对象的类都是在编译期间确定下来,不利于程序的扩展。
② 每一个代理类只能为一个接口服务,这样一来程序开发中必然产生过多的代理。
3.动态代理的特点:
动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。
4.动态代理的实现
4.1 需要解决的两个主要问题:
问题一:如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象。
(通过Proxy.newProxyInstance()实现)
问题二:当通过代理类的对象调用方法a时,如何动态的去调用被代理类中的同名方法a。
(通过InvocationHandler接口的实现类及其方法invoke())
4.2 代码实现:
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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
interface Human{
String getBelief();
void eat(String food);
}
class SuperMan implements Human{
@Override public String getBelief() { return "I believe I can fly!"; }
@Override public void eat(String food) { System.out.println("我喜欢吃" + food); } }
class HumanUtil{
public void method1(){ System.out.println("====================通用方法一====================");
}
public void method2(){ System.out.println("====================通用方法二===================="); }
}
class ProxyFactory{ public static Object getProxyInstance(Object obj){ MyInvocationHandler handler = new MyInvocationHandler();
handler.bind(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler); }
}
class MyInvocationHandler implements InvocationHandler{
private Object obj;
public void bind(Object obj){ this.obj = obj; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
HumanUtil util = new HumanUtil(); util.method1();
Object returnValue = method.invoke(obj,args);
util.method2();
return returnValue;
} }
public class ProxyTest {
public static void main(String[] args) { SuperMan superMan = new SuperMan(); Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan); String belief = proxyInstance.getBelief(); System.out.println(belief); proxyInstance.eat("四川麻辣烫");
System.out.println("*****************************");
NikeClothFactory nikeClothFactory = new NikeClothFactory();
ClothFactory proxyClothFactory = (ClothFactory) ProxyFactory.getProxyInstance(nikeClothFactory);
proxyClothFactory.produceCloth();
} }
|
体会:反射的动态性。