代理模式
- 用途:用代理对象来代理真实对象,进而达到增强真实对象功能的作用
- 大致思路:先有一个接口类,然后用一个类实现该接口,然后在主函数中再用接口类声明并调用
.newProxyInstance()
方法,并在方法参数中实现new InvocationHandler()
的复写 - 实现模式
- 静态代理
- 动态代理
静态代理
动态代理
- 实现步骤
- 代理对象和真实对象实现相同的接口
- 接口类 代理对象名称 =
Proxy.newProxyInstance(参数1,参数2,参数3)
- 使用代理对象调用方法(不会执行真实的方法,而是将调用方法中参数传入到invoke方法中的args数组中去,然后通过invoke方法的执行来实现对应方法的“覆写”,准确的说并不是覆写)
package cn.lzm.proxy;
/**
* @author
* @date 2020-05-08 10:09
*/
public interface SaleCompute {
public String saleCompute(double price);
public String show();
}
package cn.lzm.proxy;
/**
* @author
* @date 2020-05-08 10:21
*/
public class Lenevo implements SaleCompute {
@Override
public String saleCompute(double price) {
System.out.println("花了"+price+"买了一台联想电脑");
return "联想电脑";
}
@Override
public String show() {
System.out.println("我是show方法!");
return "lenovo";
}
}
package cn.lzm.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author lzm
* @date 2020-05-08 10:24
*/
public class ProxyTest {
public static void main(String[] args){
Lenevo lenevo = new Lenevo();
/**
* 代理模式
* 1.用途:用代理对象代理真实对象,达到增强真实对象功能的作用
* 2.大致思路:先有一个接口类,然后用一个类实现该接口,然后在主函数中创建该类的对象,
* 再用接口类调用.newProxyInstance()方法,并在方法参数中实现new InvocationHandler()的复写
* 3.实现方式:
* 1.静态代理:有一个类文件描述代理模式
* 2.动态代理:在内存中形成代理类
* 实现步骤:
* 1.代理对象和真实对象实现相同的接口
* 2.接口类 代理对象名称 = Proxy.newProxyInstance(参数1,参数2,参数3)
* 3.使用代理对象调用方法(不会执行真实的方法,而是将调用方法中的参数传入到invoke方法参数中的args数组
* 然后通过invoke方法的执行来实现对应方法的“复写”,准确的说不是复写)
*/
SaleCompute proxy_lenovo = (SaleCompute) Proxy.newProxyInstance(lenevo.getClass().getClassLoader(), lenevo.getClass().getInterfaces(), new InvocationHandler() {
/**
* @param proxy:代理对象
* @param method:代理对象调用的方法,被封装为对象
* @param args:代理对象调用方法时,传递的实际参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* 这里通过if...else实现了对多个需要加强的方法进行控制
*
*/
if("saleCompute".equals(method.getName()))
{
System.out.println("执行invoke1方法......");
//method.invoke方法相当于调用了对应方法的原始的内容,相当于直接调用了lenevo.saleCompute方法
Object obj = method.invoke(lenevo, args);
//打印出联想电脑,就是真实对象对应的那个方法的返回值
System.out.println((String)obj);
System.out.println(method.getName());
System.out.println(args[0]);//输出为9000
return "saleCompute";
}
else if("show".equals(method.getName()))
{
System.out.println("执行invoke2方法......");
method.invoke(lenevo);
System.out.println(method.getName());
return "show";
}
else {
return null;
}
}
});
/**
* 至于打印的compute的值为null,是因为invoke的返回值为null,而引起的
*/
String compute = proxy_lenovo.saleCompute(9000);
//打印出return "saleCompute";中的saleCompute
System.out.println(compute);
String showcompute = proxy_lenovo.show();
//System.out.println(showcompute);
}
}