代理模式分为静态代理和动态代理两种,现先写下静态代理模式
静态代理
思想:创建一个接口,然后再创建一个被代理类实现该接口和接口内的方法,再创建一个代理类同样实现接口内的方法,关键在于代理类内要持有被代理类对象,通过代理类实现的方法做一些代理动作后,通过被代理类对象去调自己的方法功能。
举例:
Star接口:
package com.example.demo.proxy;
public interface Star {
/**
* 唱歌
*
* @param money
*/
void sing(String money);
}
被代理人:
package com.example.demo.proxy;
public class KunKunProxyer implements Star {
// 代理人要获得被代理人授权 去谈需求
private CaiKunKun kun = new CaiKunKun();
private final String PROXY_FEE = "顾客花费【%s】元点了一首大碗宽面";
/**
* 代理人接唱歌需求
*
* @param money
*/
@Override
public void sing(String money) {
//做一些代理功能 被代理人是不知道的
System.out.println(String.format(PROXY_FEE, money));
if (Integer.valueOf(money) > 10) {
System.out.println("费用太高拒绝");
} else {
// 代理人可以收取代理费用
String money2 = String.valueOf(Integer.valueOf(money) - 1);
// 通知坤坤 唱歌
System.out.println("顾客点歌大碗宽面,有请坤坤");
kun.sing(money2);
}
}
}
被代理人:
package com.example.demo.proxy;
public class CaiKunKun implements Star {
private final static String SING_A_SONG = "坤坤唱首歌完赚得【%s】元";
/**
* 唱歌出场费
*
* @param money
*/
@Override
public void sing(String money) {
System.out.println(String.format(SING_A_SONG, money));
}
}
测试类:
package com.example.demo.proxy;
public class TestStaticProxy {
public static void main(String[] args) {
// 创建代理人对象
Star kunProxyer = new KunKunProxyer();
kunProxyer.sing("2");
}
}
结果:
"C:\Program Files\Java\jdk1.8.0_251\bin\java.exe"
顾客花费【2】元点了一首大碗宽面
顾客点歌大碗宽面,有请坤坤
坤坤唱首歌完赚得【1】元
动态代理
思想:相比静态代理,动态代理不用自己再写代理类,而是依赖jdk自带的类和方法动态生成代理类对象和一些拓展功能,再通过代理类对象去调用接口方法,因此动态代理主要理解和掌握jdk 自动生成代理类的过程(基于被代理类实现接口的情况)。
现举个例子帮助理解:
package com.example.demo.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestProxyProduce {
public static void main(String[] args) {
//创建被代理类对象
Star kunKun = new CaiKunKun();
//利用JDK的Proxy类生成代理类对象
Star kunkunProxy = (Star) Proxy.newProxyInstance(kunKun.getClass().getClassLoader(), kunKun.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 获得方法的参数
String money = (String) args[0];
String money2 = String.valueOf(Integer.valueOf(money) * 0.2);
// 利用反射获得执行方法
String name = method.getName();
if ("sing".equals(name)) {
System.out.println("代理坤坤唱歌,收取代理费用:" + (Integer.valueOf(money) * 0.8));
kunKun.sing(money2);
}
return null;
}
});
kunkunProxy.sing("5");
}
}
结果:
代理坤坤唱歌,收取代理费用:4.0
坤坤唱首歌完赚得【1.0】元
以上是对动态代理思想的理解,可以刚入门同学的一些帮助,若想深入理解需要看下Proxy 类的源码,深究下生成代理类的过程。