静态代理的缺点是只能代理一个主题接口,后期想增加代理,还得修改
而动态代理是一个代理工作器可以代替多个“代理主题”代理工作,核心逻辑还是被代理者们来实现,只要代理工作一样,这个代理工作器就可以代理。
要求:
1、编写代理类,实现InvocationHandler接口,重写invoke方法
2、用Proxy.newProxyInstance创建代理对象
3、方法调用
主题接口和实现类:
public interface TestA {
void runA();
}
public class ImplA implements TestA {
@Override
public void runA() {
System.out.println("我是A接口的实现类,我在运行我重写的runA方法.....");
}
}
public interface TestB {
void runB();
}
public class ImplB implements TestB {
@Override
public void runB() {
System.out.println("我是B接口的实现类,我在运行我重写的runB方法.....");
}
}
代理类:
public class Handle implements InvocationHandler {
private Object object;
public Handle(Object object) {
this.object = object;
}
/**
*
* @param proxy 代理者对象
* @param method 被代理者要执行的方法
* @param args 被代理者执行方法需要的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(proxy.getClass().getName()+"开始执行代理工作...");
System.out.println(method.getName()+"开始执行....");
Object value = method.invoke(object,args);
System.out.println(method.getName()+"执行结束");
System.out.println(proxy.getClass().getName()+"执行代理工作结束");
return value;
}
}
测试类:
public class Test {
public static void main(String[] args) {
//执行代理impA的工作
TestA a = new ImplA();
ClassLoader classLoader = a.getClass().getClassLoader();
Class<?>[] interfaces = a.getClass().getInterfaces();
Handle handle = new Handle(a);
/**
* newProxyInstance的三个参数
* 1、被代理者的类加载器
* 2、被代理者实现的接口们
* 3、代理者的对象
*/
TestA testA = (TestA) Proxy.newProxyInstance(classLoader, interfaces, handle);
testA.runA();
System.out.println("===============================");
//执行代理impB的工作
TestB b = new ImplB();
ClassLoader classLoaderB = b.getClass().getClassLoader();
Class<?>[] interfacesB = b.getClass().getInterfaces();
Handle handleB = new Handle(b);
/**
* newProxyInstance的三个参数
* 1、被代理者的类加载器
* 2、被代理者实现的接口们
* 3、代理者的对象
*/
TestB testB = (TestB) Proxy.newProxyInstance(classLoaderB, interfacesB, handleB);
testB.runB();
}
}
测试结果:
E:\Java\jdk\bin\java.exe "-javaagent:E:\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=61915:E:\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath E:\Java\jdk\jre\lib\charsets.jar;E:\Java\jdk\jre\lib\deploy.jar;E:\Java\jdk\jre\lib\ext\access-bridge-64.jar;E:\Java\jdk\jre\lib\ext\cldrdata.jar;E:\Java\jdk\jre\lib\ext\dnsns.jar;E:\Java\jdk\jre\lib\ext\jaccess.jar;E:\Java\jdk\jre\lib\ext\jfxrt.jar;E:\Java\jdk\jre\lib\ext\localedata.jar;E:\Java\jdk\jre\lib\ext\nashorn.jar;E:\Java\jdk\jre\lib\ext\sunec.jar;E:\Java\jdk\jre\lib\ext\sunjce_provider.jar;E:\Java\jdk\jre\lib\ext\sunmscapi.jar;E:\Java\jdk\jre\lib\ext\sunpkcs11.jar;E:\Java\jdk\jre\lib\ext\zipfs.jar;E:\Java\jdk\jre\lib\javaws.jar;E:\Java\jdk\jre\lib\jce.jar;E:\Java\jdk\jre\lib\jfr.jar;E:\Java\jdk\jre\lib\jfxswt.jar;E:\Java\jdk\jre\lib\jsse.jar;E:\Java\jdk\jre\lib\management-agent.jar;E:\Java\jdk\jre\lib\plugin.jar;E:\Java\jdk\jre\lib\resources.jar;E:\Java\jdk\jre\lib\rt.jar;F:\IdeaProjects\testProxy\out\production\testProxy dynamicProxy.Test
com.sun.proxy.$Proxy0开始执行代理工作...
runA开始执行....
我是A接口的实现类,我在运行我重写的runA方法.....
runA执行结束
com.sun.proxy.$Proxy0执行代理工作结束
===============================
com.sun.proxy.$Proxy1开始执行代理工作...
runB开始执行....
我是B接口的实现类,我在运行我重写的runB方法.....
runB执行结束
com.sun.proxy.$Proxy1执行代理工作结束
Process finished with exit code 0