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

转载自 设计模式之动态代理模式实战

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值