设计模式之动态代理模式实战详解编程语言

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

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/16507.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论