zoukankan      html  css  js  c++  java
  • 设计模式之动态代理模式实战

          动态代理在我们工作当中应用相当广泛,如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的方法是不能被动态代理的。

  • 相关阅读:
    ionic localstorage
    angular 中文鏈接
    把jqmobi 變成jQuery 的插件 從此使用jQuery
    jqmobi 的一些設置
    ionic ngcordova map 地圖
    ionic pull to refresh 下拉更新頁面
    json 對象的序列化
    鍵盤彈出,頁面佈局被推上去了.....
    Cordova V3.0.0中config.xml配置文件的iOS Configuration
    android ios 只能輸入數字 不能輸入小數點的 函數 cordova
  • 原文地址:https://www.cnblogs.com/rinack/p/9733870.html
Copyright © 2011-2022 走看看