• 设计模式之动态代理模式实战


          动态代理在我们工作当中应用相当广泛,如Srping AOP就是动态代理的在开源框架的比较出名的应用。动态代理有两种试:一是通过JDK自带的API实现动态代理,二是通过别的字节码框架实现,如cglib。需要注意的是JDK只能针对接口实现动态代理,不能代理普通类,使用具有局限性。而cglib可以代理接口及所有的普通类。

    用户接口

    public interface UserInterface {
        boolean saveUser(User user);
    }

    用户接口实现

    public class UserInterfaceImpl implements UserInterface {
    
        @Override
        public boolean saveUser(User user) {
            System.out.println("保存用户: " + user.getName());
            return true;
        }
    
    }

    测试

    public class Test {
        
        public static void main(String[] args) {
    
            // JDK动态代理
            testJDKProxy();
            // Cglib接口代理
            testCglibInterfaceProxy();
            // Cglib类代理
            testCglibClassProxy();
    
        }
    
        private static void testJDKProxy() {
            
            User user = new User();
            user.setName("tom");
            UserProxy.getUserProxy().saveUser(user);
            
        }
    
        static class UserProxy {
    
            private static final InvocationHandler USER_HANDLE = new InvocationHandler() {
    
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("JDK接口动态代理-开始保存用户");
                    Object result = method.invoke(new UserInterfaceImpl(), args);
                    System.out.println("JDK接口动态代理-保存用户结果: " + result);
                    System.out.println();
                    return result;
                }
    
            };
    
            public static UserInterface getUserProxy() {
                
                UserInterface userInterface = (UserInterface) Proxy.newProxyInstance(UserProxy.class.getClassLoader(),
                        new Class[] { UserInterface.class }, USER_HANDLE);
                return userInterface;
                
            }
    
        }
    
        private static void testCglibInterfaceProxy() {
    
            User user = new User();
            user.setName("tom");
            UserCglibProxy.getUserProxy().saveUser(user);
    
        }
    
        static class UserCglibProxy {
    
            private static final net.sf.cglib.proxy.InvocationHandler USER_HANDLE = new net.sf.cglib.proxy.InvocationHandler() {
                
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
                    System.out.println("Cglib接口动态代理-开始保存用户");
                    Object result = method.invoke(new UserInterfaceImpl(), args);
                    System.out.println("Cglib接口动态代理-保存用户结果: " + result);
                    System.out.println();
                    return result;
    
                }
    
            };
    
            public static UserInterface getUserProxy() {
    
                UserInterface userInterface = (UserInterface) net.sf.cglib.proxy.Proxy.newProxyInstance(
                        UserCglibProxy.class.getClassLoader(), new Class[] { UserInterface.class }, USER_HANDLE);
                return userInterface;
    
            }
    
        }
    
        private static void testCglibClassProxy() {
    
            User user = new User();
            user.setName("tom");
            UserInterfaceImpl userImpl = (UserInterfaceImpl) ClassCgLibProxy.getUserProxy(new UserInterfaceImpl());
            userImpl.saveUser(user);
    
        }
    
        static class ClassCgLibProxy {
    
            private static final MethodInterceptor USER_HANDLE = new MethodInterceptor() {
    
                @Override
                public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    
                    System.out.println("Cglib类动态代理-开始保存用户");
                    Object result = proxy.invokeSuper(obj, args);
                    System.out.println("Cglib类动态代理-保存用户结果: " + result);
                    System.out.println();
                    return result;
    
                }
    
            };
    
            public static Object getUserProxy(Object target) {
                
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(target.getClass());
                enhancer.setCallback(USER_HANDLE);
                return enhancer.create();
    
            }
    
        }
    
    }

    结果输出:

    JDK接口动态代理-开始保存用户
    保存用户: tom
    JDK接口动态代理-保存用户结果: true
    
    Cglib接口动态代理-开始保存用户
    保存用户: tom
    Cglib接口动态代理-保存用户结果: true
    
    Cglib类动态代理-开始保存用户
    保存用户: tom
    Cglib类动态代理-保存用户结果: true

    从例子看出,使用也并不复杂,动态代理与静态代理最主要的区别在于,静态代理是编译期间就确定好的代理关系,而动态代理是运行期间由JVM通过反射等技术生成的代理对象,不存在class文件,代理类与被代理类之间的关系是继承关系,所以,普通类final的方法是不能被动态代理的。

  • 相关阅读:
    Linux性能调优
    Linux动态库搜索路径的技巧
    [转]Linux动态库的种种要点
    [转]谈谈Linux下动态库查找路径的问题
    性能测试的几种业务模型设计
    性能测试解惑之并发压力
    一个系统的最大并发用户数为1100,怎么能推算出该系统的支持最大用户数
    IP欺骗
    关于Cocos2d-x随机数的生成
    关于Cocos2d-x节点和精灵节点的坐标、位置以及大小的设置
  • 原文地址:https://www.cnblogs.com/rinack/p/9733870.html
Copyright © 2020-2023  润新知