假设我们有一个叫做FileSystem
接口,UnixFileSystem
类实现了FileSystem
接口,我们可以使用JDK动态代理
的方式给FileSystem
的接口方法执行前后都添加日志输出。
com.anbai.sec.proxy.FileSystem示例代码:
package com.anbai.sec.proxy;
import java.io.File;
import java.io.Serializable;
/**
* Creator: yz
* Date: 2020/1/14
*/
public interface FileSystem extends Serializable {
String[] list(File file);
}
com.anbai.sec.proxy.UnixFileSystem示例代码:**
package com.anbai.sec.proxy;
import java.io.File;
/**
* Creator: yz
* Date: 2020/1/14
*/
public class UnixFileSystem implements FileSystem {
/* -- Disk usage -- */
public int spaceTotal = 996;
@Override
public String[] list(File file) {
System.out.println("正在执行[" + this.getClass().getName() + "]类的list方法,参数:[" + file + "]");
return file.list();
}
}
com.anbai.sec.proxy.JDKInvocationHandler示例代码:
package com.anbai.sec.proxy;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* Creator: yz
* Date: 2020/1/14
*/
public class JDKInvocationHandler implements InvocationHandler, Serializable {
private final Object target;
public JDKInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 为了不影响测试Demo的输出结果,这里忽略掉toString方法
if ("toString".equals(method.getName())) {
return method.invoke(target, args);
}
System.out.println("即将调用[" + target.getClass().getName() + "]类的[" + method.getName() + "]方法...");
Object obj = method.invoke(target, args);
System.out.println("已完成[" + target.getClass().getName() + "]类的[" + method.getName() + "]方法调用...");
return obj;
}
}
com.anbai.sec.proxy.FileSystemProxyTest示例代码:
package com.anbai.sec.proxy;
import java.io.File;
import java.lang.reflect.Proxy;
import java.util.Arrays;
/**
* Creator: yz
* Date: 2020/1/14
*/
public class FileSystemProxyTest {
public static void main(String[] args) {
// 创建UnixFileSystem类实例
FileSystem fileSystem = new UnixFileSystem();
// 使用JDK动态代理生成FileSystem动态代理类实例
FileSystem proxyInstance = (FileSystem) Proxy.newProxyInstance(
FileSystem.class.getClassLoader(),// 指定动态代理类的类加载器
new Class[]{FileSystem.class}, // 定义动态代理生成的类实现的接口
new JDKInvocationHandler(fileSystem)// 动态代理处理类
);
System.out.println("动态代理生成的类名:" + proxyInstance.getClass());
System.out.println("----------------------------------------------------------------------------------------");
System.out.println("动态代理生成的类名toString:" + proxyInstance.toString());
System.out.println("----------------------------------------------------------------------------------------");
// 使用动态代理的方式UnixFileSystem方法
String[] files = proxyInstance.list(new File("."));
System.out.println("----------------------------------------------------------------------------------------");
System.out.println("UnixFileSystem.list方法执行结果:" + Arrays.toString(files));
System.out.println("----------------------------------------------------------------------------------------");
boolean isFileSystem = proxyInstance instanceof FileSystem;
boolean isUnixFileSystem = proxyInstance instanceof UnixFileSystem;
System.out.println("动态代理类[" + proxyInstance.getClass() + "]是否是FileSystem类的实例:" + isFileSystem);
System.out.println("----------------------------------------------------------------------------------------");
System.out.println("动态代理类[" + proxyInstance.getClass() + "]是否是UnixFileSystem类的实例:" + isUnixFileSystem);
System.out.println("----------------------------------------------------------------------------------------");
}
}
程序执行结果:
动态代理生成的类名:class com.sun.proxy.$Proxy0
----------------------------------------------------------------------------------------
动态代理生成的类名toString:com.anbai.sec.proxy.UnixFileSystem@194d6112
----------------------------------------------------------------------------------------
即将调用[com.anbai.sec.proxy.UnixFileSystem]类的[list]方法...
正在执行[com.anbai.sec.proxy.UnixFileSystem]类的list方法,参数:[.]
已完成[com.anbai.sec.proxy.UnixFileSystem]类的[list]方法调用...
----------------------------------------------------------------------------------------
UnixFileSystem.list方法执行结果:[javaweb-sec.iml, javaweb-sec-source, pom.xml, README.md, .gitignore, gitbook, .git, jni, .idea]
----------------------------------------------------------------------------------------
动态代理类[class com.sun.proxy.$Proxy0]是否是FileSystem类的实例:true
----------------------------------------------------------------------------------------
动态代理类[class com.sun.proxy.$Proxy0]是否是UnixFileSystem类的实例:false
----------------------------------------------------------------------------------------