假设我们有一个叫做FileSystem接口,UnixFileSystem类实现了FileSystem接口,我们可以使用JDK动态代理的方式给FileSystem的接口方法执行前后都添加日志输出。
    com.anbai.sec.proxy.FileSystem示例代码:

    1. package com.anbai.sec.proxy;
    2. import java.io.File;
    3. import java.io.Serializable;
    4. /**
    5. * Creator: yz
    6. * Date: 2020/1/14
    7. */
    8. public interface FileSystem extends Serializable {
    9. String[] list(File file);
    10. }


    com.anbai.sec.proxy.UnixFileSystem示例代码:**

    1. package com.anbai.sec.proxy;
    2. import java.io.File;
    3. /**
    4. * Creator: yz
    5. * Date: 2020/1/14
    6. */
    7. public class UnixFileSystem implements FileSystem {
    8. /* -- Disk usage -- */
    9. public int spaceTotal = 996;
    10. @Override
    11. public String[] list(File file) {
    12. System.out.println("正在执行[" + this.getClass().getName() + "]类的list方法,参数:[" + file + "]");
    13. return file.list();
    14. }
    15. }

    com.anbai.sec.proxy.JDKInvocationHandler示例代码:

    1. package com.anbai.sec.proxy;
    2. import java.io.Serializable;
    3. import java.lang.reflect.InvocationHandler;
    4. import java.lang.reflect.Method;
    5. /**
    6. * Creator: yz
    7. * Date: 2020/1/14
    8. */
    9. public class JDKInvocationHandler implements InvocationHandler, Serializable {
    10. private final Object target;
    11. public JDKInvocationHandler(Object target) {
    12. this.target = target;
    13. }
    14. @Override
    15. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    16. // 为了不影响测试Demo的输出结果,这里忽略掉toString方法
    17. if ("toString".equals(method.getName())) {
    18. return method.invoke(target, args);
    19. }
    20. System.out.println("即将调用[" + target.getClass().getName() + "]类的[" + method.getName() + "]方法...");
    21. Object obj = method.invoke(target, args);
    22. System.out.println("已完成[" + target.getClass().getName() + "]类的[" + method.getName() + "]方法调用...");
    23. return obj;
    24. }
    25. }

    com.anbai.sec.proxy.FileSystemProxyTest示例代码:

    1. package com.anbai.sec.proxy;
    2. import java.io.File;
    3. import java.lang.reflect.Proxy;
    4. import java.util.Arrays;
    5. /**
    6. * Creator: yz
    7. * Date: 2020/1/14
    8. */
    9. public class FileSystemProxyTest {
    10. public static void main(String[] args) {
    11. // 创建UnixFileSystem类实例
    12. FileSystem fileSystem = new UnixFileSystem();
    13. // 使用JDK动态代理生成FileSystem动态代理类实例
    14. FileSystem proxyInstance = (FileSystem) Proxy.newProxyInstance(
    15. FileSystem.class.getClassLoader(),// 指定动态代理类的类加载器
    16. new Class[]{FileSystem.class}, // 定义动态代理生成的类实现的接口
    17. new JDKInvocationHandler(fileSystem)// 动态代理处理类
    18. );
    19. System.out.println("动态代理生成的类名:" + proxyInstance.getClass());
    20. System.out.println("----------------------------------------------------------------------------------------");
    21. System.out.println("动态代理生成的类名toString:" + proxyInstance.toString());
    22. System.out.println("----------------------------------------------------------------------------------------");
    23. // 使用动态代理的方式UnixFileSystem方法
    24. String[] files = proxyInstance.list(new File("."));
    25. System.out.println("----------------------------------------------------------------------------------------");
    26. System.out.println("UnixFileSystem.list方法执行结果:" + Arrays.toString(files));
    27. System.out.println("----------------------------------------------------------------------------------------");
    28. boolean isFileSystem = proxyInstance instanceof FileSystem;
    29. boolean isUnixFileSystem = proxyInstance instanceof UnixFileSystem;
    30. System.out.println("动态代理类[" + proxyInstance.getClass() + "]是否是FileSystem类的实例:" + isFileSystem);
    31. System.out.println("----------------------------------------------------------------------------------------");
    32. System.out.println("动态代理类[" + proxyInstance.getClass() + "]是否是UnixFileSystem类的实例:" + isUnixFileSystem);
    33. System.out.println("----------------------------------------------------------------------------------------");
    34. }
    35. }

    程序执行结果:

    1. 动态代理生成的类名:class com.sun.proxy.$Proxy0
    2. ----------------------------------------------------------------------------------------
    3. 动态代理生成的类名toString:com.anbai.sec.proxy.UnixFileSystem@194d6112
    4. ----------------------------------------------------------------------------------------
    5. 即将调用[com.anbai.sec.proxy.UnixFileSystem]类的[list]方法...
    6. 正在执行[com.anbai.sec.proxy.UnixFileSystem]类的list方法,参数:[.]
    7. 已完成[com.anbai.sec.proxy.UnixFileSystem]类的[list]方法调用...
    8. ----------------------------------------------------------------------------------------
    9. UnixFileSystem.list方法执行结果:[javaweb-sec.iml, javaweb-sec-source, pom.xml, README.md, .gitignore, gitbook, .git, jni, .idea]
    10. ----------------------------------------------------------------------------------------
    11. 动态代理类[class com.sun.proxy.$Proxy0]是否是FileSystem类的实例:true
    12. ----------------------------------------------------------------------------------------
    13. 动态代理类[class com.sun.proxy.$Proxy0]是否是UnixFileSystem类的实例:false
    14. ----------------------------------------------------------------------------------------