接上一篇:静态代理
有人私信我文章代码都是截图的想用copy一份很麻烦,OK
哈哈,主要是图省事,往后我尽量贴出代码。
还是上篇的需求,商品出售前后需要做一些增强。
一、先创建一个商品出售的接口
package com.bailan.proxy.dynamicproxy;
public interface OrderService {
String sell(String name);
String show();
}
二、然后对其进行简单的实现
package com.bailan.proxy.dynamicproxy;
public class OrderServiceImpl implements OrderService {
@Override
public String sell(String name) {
System.out.println("出售了商品"+name);
return name;
}
@Override
public String show() {
String s = "所有商品";
System.out.println("查看所有商品");
return s;
}
}
三、然后新建个类用来测试动态代理
我这里使用junit测试 就懒得写main方法调用了,代码都注视了。
package com.bailan.proxy.dynamicproxy;
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class OrderServiceProxy {
private OrderServiceImpl orderImpl = new OrderServiceImpl();
@Test
public void orderSellProxy() {
/**
* 这里三个参数分别是
* 通过Proxy类的newProxyInstance方法创建代理对象,我们来看下方法中的参数
* 第一个参数:orderImpl.getClass().getClassLoader(),使用handler对象的classloader对象来加载我们的代理对象
* 第二个参数:orderImpl.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口中的所有方法
* 第三个参数:handler,一个代理类的调用处理程序,每个代理类的调用处理程序都必须实现InvocationHandler接口
*/
OrderService orderService = (OrderService) Proxy.newProxyInstance(orderImpl.getClass().getClassLoader(),
orderImpl.getClass().getInterfaces(), new InvocationHandler() {
/**
* proxy:产生的代理对象的引用
* method:当前正在调用的目标类的方法
* params:只在执行的方法中的参数。
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//选择性增强
if ("sell".equals(method.getName())) {
init();
String invoke = (String) method.invoke(orderImpl, args);
last();
//返回值增强
return "赠送键盘," + invoke;
} else {
Object invoke = method.invoke(orderImpl, args);
return invoke;
}
}
});
//测试
String s = orderService.sell("电脑1");
System.out.println(s);
}
public void init() {
System.out.println("售前准备");
}
public void last() {
System.out.println("售后记录");
}
}
四、来看看执行结果
完全不干扰其他代码,使用匿名内部类无需新建代理类,想在哪里用就哪里用。
image.png
五、最后根据网上资料查询总结如下
代理模式
代理模式是常用的java设计模式(spring 中的AOP,struts2拦截器就是动态代理实现的),他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处 理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。
代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的 对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
按照代理的创建时期,代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
动态代理实现
java.lang.reflect.Proxy,
Proxy 提供用于创建动态代理类和实例的静态方法.
newProxyInstance()
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
外站参考资料
java的动态代理机制详解
http://www.cnblogs.com/xiaoluo501395377/p/3383130.html
网友评论