博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之动态代理模式实战
阅读量:2002 次
发布时间:2019-04-28

本文共 3329 字,大约阅读时间需要 11 分钟。

转载自 

昨天分享了静态代理的概念及存在的缺点,所以今天讲的动态代理模式十分重要。动态代理在我们工作当中应用相当广泛,如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的方法是不能被动态代理的。

你可能感兴趣的文章
python 多进程之进程池的操作
查看>>
flask整理之 flask程序中的debug模式
查看>>
比特币,父母这一辈能接受吗?
查看>>
SnapEx的新感觉,对新手很友好
查看>>
首个聚合器怎么产生的,并运用领域在什么
查看>>
区块链技术应用,最先医疗行业
查看>>
新币上市旧币会降价吗
查看>>
当博士进入币圈会怎么样
查看>>
《增长黑客》(肖恩·艾利斯)学习笔记——第二部分 实战
查看>>
python使用HTMLTestRunner查看运行函数
查看>>
linux下安装jenkins+git+python
查看>>
解决uiautomatorviewer中添加xpath的方法
查看>>
jenkins安装提示Please wait while Jenkins is getting ready to work...(Jenkins访问资源慢的问题)
查看>>
性能测试的必要性评估以及评估方法
查看>>
Spark学习——利用Mleap部署spark pipeline模型
查看>>
Oracle创建表,修改表(添加列、修改列、删除列、修改表的名称以及修改列名)
查看>>
使用redis实现订阅功能
查看>>
对称加密整个过程
查看>>
java内存模型
查看>>
volatile关键字
查看>>