第一段原文链接:JDK动态代理案例_jdk动态代理实例_7Euro的博客-CSDN博客
原理
JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,
InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。
代码实现
创建接口及实现类
public interface SomeService {
void doSome();
void doOther();
public class SomeServiceImpl implements SomeService {
@Override
public void doSome() {
System.out.println("doSome.......");
}
@Override
public void doOther() {
System.out.println("doOther.......");
}
创建第三方增强方法
public class ServiceTools {
public static void doLog() {
System.out.println("添加日志");
}
public static void doTrans() {
System.out.println("执行事务");
}
创建InvocationHandler接口实现类
public class MyInvocationHandler implements InvocationHandler {
private Object object;
public MyInvocationHandler(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行了MyInvocationHandler中的invoke方法");
// 通过代理对象执行方法时,会调用执行这个invoke
Object res = null;
ServiceTools.doLog();
// 执行目标类的方法,通过Method类实现
res = method.invoke(object, args); // SomeServiceImpl.doSome;SomeServiceImpl.doOther;
ServiceTools.doTrans();
return res;
}
}
编写测试类
public class MyApp {
public static void main(String[] args) {
SomeService service = new SomeServiceImpl();
// 创建InvocationHandler对象
InvocationHandler invocationHandler = new MyInvocationHandler(service);
// 使用Proxy创建代理
SomeService proxy = (SomeService) Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), invocationHandler);
// 通过代理执行方法,会调用handler中的invoke()
proxy.doSome();
}
}
测试结果
执行了MyInvocationHandler中的invoke方法
添加日志
doSome.......
执行事务
第二段案例比较好原文链接:
代理模式--JDK动态代理案例_jdk动态代理实例_Java界的小白的博客-CSDN博客
JDK动态代理--生活代码案例
通过以上生活案例,我们来写代码,总是代理模式和生活的意思一样,现在商业处处都是代理,买房子,微商等等,有了这些代理,客户获取了更好的感受。
1.卖电脑接口2
/**
* 真实对象和代理对象实现相同的卖电脑接口
*/
public interface SaleComputer {
String pay(double money);
void show();
}
2.北京联想公司(真实对象)
public class Lenovo implements SaleComputer {
@Override
public String pay(double money) {
System.out.println("客户支付了"+money+"买了一台电脑");
return "联想电脑";
}
@Override
public void show() {
System.out.println("展示电脑");
}
}
3.天津代理商(代理对象)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 增强代理对象测试
*/
public class ProxyTest {
public static void main(String[] args) {
Lenovo lenovo = new Lenovo();
/*
* java.lang.reflect.Proxy提供用于创建动态代理类和实例的静态方法,大家可以查看JDK文档。
* 1.Proxy.newProxyInstance()通过调用newInstance 方法创建代理实例。
* 2.方法中有三个参数
* ClassLoader loader:定义代理类的类加载器(即真实对象)
* Class<?>[] interfaces:真实对象实现的接口数组
* InvocationHandler h:调用处理程序,执行方法。
*/
SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(),
lenovo.getClass().getInterfaces(), new InvocationHandler() {
@Override
//invoke方法是核心代理逻辑思想,代理对象调用的所有方法都会触发该方法执行
//增强方式有三种:1.增强参数 2.增强返回值 3.增强方法体
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
* 三个参数
* 1.proxy:就是代理对象本身
* 2.method:代理对象调用的方法,被封装为的对象。简单说 谁在运行调用,这个method就是谁。
* 3.args:代理对象调用方法时,传递的实际参数
*/
//增强参数
if (method.getName().equals("pay")) {
//增强参数,代理需要赚取利润,代理修改了参数。
//这里args[0]代表方法的第一个参数。
double money = (double) args[0];
money = money * 1.2;
//增强方法体
System.out.println("买电脑专车接送");
//修改了方法参数 这里method.invok就是调用方法。
String computer = (String) method.invoke(lenovo, money);
//增强方法体
System.out.println("买电脑免费配送");
//增强返回值
return computer+"送鼠标垫";
} else {
//如果没有,那么就原样输出
Object obj = method.invoke(lenovo, args);
return obj;
}
}
});
String computer = proxy_lenovo.pay(5000);
System.out.println(computer);
proxy_lenovo.show();
}
}
4.测试结果