引入代理模式的原因是我们在实现Filter(过滤)时,需要对某些用户输入的敏感词汇进行过滤,全部替换为"***",而原有对象是不具备相关方法的,因此需要引入代理模式。厂家---》代理---》用户。代理可以对厂家的某些方法进行加工增强
设计模式:一些通用的解决固定问题的方式。增强对象的功能一般使用如下两种设计模式:
1. 装饰模式
2. 代理模式
* 概念:
(1). 真实对象:被代理的对象
(2). 代理对象:
(3). 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
* 实现方式:
(1). 静态代理:有一个类文件描述代理模式
(2). 动态代理:在内存中形成代理类
* 实现步骤:
A. 代理对象和真实对象实现相同的接口
B. 代理对象 = Proxy.newProxyInstance();
C. 使用代理对象调用方法。
D. 增强方法
* 增强方式:
A. 增强参数列表
B. 增强返回值类型
案例:实现模拟客户从代理购买电脑案例
1、客户从代理购买电脑,代理实际花了客户的0.8被价格---相当于增强了传入参数。
2、代理为了满足客户贪小便宜心理,送给客户一些商品---相当于增强返回值。
(1)、接口
saleComputer.java
public interface saleComputer {
public String sale(double money);
public void show();
}
(2)、实现类
thinkpad.java
public class thinkpad implements saleComputer {
@Override
public String sale(double money) {
System.out.println("花了"+money+"买电脑");
return "thinkpad";
}
@Override
public void show() {
System.out.println("i am thinkpad show()");
}
}
(3)、测试类
ProxyTest.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
thinkpad tp = new thinkpad();
/**
* Proxy.newProxyInstance()传入的参数说明
* 1.类加载器,用哪个类加载器去加载代理对象:真实对象.getClass().getClassLoader()
* 2.动态代理类需要实现的接口:真实对象.getClass().getClassLoader()
* 3.动态代理方法在执行时,会调用h里面的invoke方法去执行
*/
saleComputer proxy_thinkpad = (saleComputer) Proxy.newProxyInstance(tp.getClass().getClassLoader(), tp.getClass().getInterfaces(), new InvocationHandler() {
/**
*代理对象执行接口中的方法时,一定会自行invoke()方法
* @param proxy:就是代理对象,newProxyInstance方法的返回对象
* @param method:代理对象调用的方法
* @param args:代理对象调用方法时传入的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// System.out.println("invoke() method.getName()---"+method.getName());
// System.out.println("invoke() args[0]---"+args[0]);
//
System.out.println("i am invoke()");
//1、增强方法的参数---改变方法传入参数的内容。首先需要确保方法是有参数的
if(method.getName().contains("sale")){
//改变传入参数
args[0] = (double)args[0]*0.8;
Object obj = method.invoke(tp, args);
//2、增强方法的返回参数---就是给返回值添加内容
return obj+"送你个鼠标键盘套件";
//3.增强方法体其实就是改变执行逻辑
}else{
//使用真实对象调用该方法
Object obj = method.invoke(tp, args);
return obj;//这个返回的值就是后面代理对象调用方法时的接收值
}
}
});
//我们通过代理去执行sale方法,增强sale方法
String ret = proxy_thinkpad.sale(7800.0);
System.out.println(ret);
}
}