代理模式
代理模式
静态代理
/*
* 代理模式
* */
public class Demo {
public static void main(String[] args) {
// 实例化被代理类
Demo01Impl demo01 = new Demo01Impl();
// 使用被代理类实例化代理类
ProxyServer proxyServer = new ProxyServer(demo01);
/*
* 此时有参构造后,代理类中的 private Demo01 demo01 = new DemoImpl();
* */
proxyServer.method01();
/*
* 此时进入代理类的method01()中
* checkMethod01();
* demo01.method01();
* 先执行checkMethod01(),然后调用这个private Demo01 demo01 = new DemoImpl();的method01()
*
* 此时结果为:
* method01的检查工作
* 被代理类method01
* */
}
}
// 接口
interface Demo01 {
void method01();
}
// 被代理类
class Demo01Impl implements Demo01 {
@Override
public void method01() {
System.out.println("被代理类method01");
}
}
// 代理类
class ProxyServer implements Demo01 {
private Demo01 demo01;
// 在构造器中对demo01初始化
public ProxyServer(Demo01 demo01) {
this.demo01 = demo01;
}
public void checkMethod01() {
System.out.println("method01的检查工作");
}
@Override
public void method01() {
checkMethod01();
demo01.method01();
}
}
动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* 使用反射,动态代理
* */
public class ReDemo {
public static void main(String[] args) {
// 参数是一个被代理类对象
// proxyInstance就是代理类对象
Demo proxyInstance01 = (Demo) ProxyFactory.getProxyInstance(new DemoImpl01());
Demo proxyInstance02 = (Demo) ProxyFactory.getProxyInstance(new DemoImpl02());
proxyInstance01.method();
proxyInstance02.method();
}
}
// 接口
interface Demo {
void method();
}
// 被代理类
class DemoImpl01 implements Demo{
@Override
public void method() {
System.out.println("DemoImpl01 => method()");
}
}
// 被代理类
class DemoImpl02 implements Demo{
@Override
public void method() {
System.out.println("DemoImpl02 => method()");
}
}
/*
* 问题:
* 1.如何根据加载到内存中的被代理类对象,动态创建一个代理类及其对象?
* 2.通过代理类的对象调用方法时如何让被代理类调用同名的方法
* */
class ProxyFactory {
public static Object getProxyInstance(Object o) { // o是被代理类对象
MyInvocationHandler handler = new MyInvocationHandler();
handler.bind(o);
return Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(),handler);
}
}
class MyInvocationHandler implements InvocationHandler {
// 声明是Object,但是赋值时需要被代理类的对象进行赋值
private Object object;
public void bind(Object o) {
this.object = o;
}
// 当我们通过代理类的对象,调用方法是,就是自动调用如下的方法:invoke()
// 将被代理类要执行的方法的功能就声明在invoke()中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 方法之前
System.out.println("方法之前");
System.out.println(method + " ===> 参数:" + Arrays.toString(args));
// 原方法
// method就是代理类对象调用的方法,此方法也就作为了被代理类调用的方法
Object returnValue = method.invoke(object, args);
return returnValue;
// 方法之后
System.out.println("方法之后");
}
}