zoukankan      html  css  js  c++  java
  • JDK动态代理

    JDK动态代理
    JDK的动态代理,是设计模式中代理模式的一种,主要用来做方法的增强,让你可以在不修改源码的情况下,增强一些方法,在方法执行前后做任何你想做的事情(甚至根本不去执行这个方法),因为在InvocationHandler的invoke方法中,你可以直接获取正在调用方法对应的Method对象,具体应用的话,比如可以添加调用日志,做事务控制等。spring的面向前面编程(AOP)当中其中的一种实现方式就是采用了JDK动态代理的来实现的
     
    JDK动态代理实现的步骤
    一个典型的动态代理创建对象过程可分为以下四个步骤:
    1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);
    2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
    Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});
    3、通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
    Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
    4、通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入
    Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
    为了简化对象创建过程,Proxy类中的newInstance方法封装了2~4,只需两步即可完成代理对象的创建。
    生成的ProxySubject继承Proxy类实现Subject接口,实现的Subject的方法实际调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的的方法(Object result=method.invoke(proxied,args))
     
    代码的实现
     
    1.创建代理处理器
      并使用目标对象(被代理的对象)来创建代理对象
    package com.jdkproxy.hadler;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    import com.jdkproxy.service.UserService;
    
    public class ProxyObject implements InvocationHandler{
    
        private Object targetObject;
        
    
        /**
         * 通过目标对象创建代理对象(代理对象和目标对象需要实现相同的接口)
         * @param targetObject
         * @return
         */
        public Object createProxyWithTarget(Object targetObject) {
            this.targetObject = targetObject;
            
            /**
             * loader.目标对象的类加载器
             * interface:目标对象实现的接口
             * h:InvocationHandler:代理对象,也就是当前类
             */
            return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                    targetObject.getClass().getInterfaces(),this);
        }
    
        /**
         * 参数一:代理对象
         * 参数二:被代理的方法
         * 参数三:被代理方法的参数
         *  */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //使用被代理的目标对象来调用真实调用的函数
            System.out.println("调用前====================");
            Object obj = method.invoke(targetObject, args);
            System.out.println("调用后====================");
            return obj;//被代理对象的执行方法后的返回值
        }
    
    }

    2.调用代理对象,实现对象的代理

    package com.jdkproxy.test;
    
    import org.junit.Test;
    
    import com.jdkproxy.hadler.ProxyObject;
    import com.jdkproxy.model.User;
    import com.jdkproxy.service.UserService;
    import com.jdkproxy.service.UserServiceImp;
    
    public class ProxyTest {
        
        @Test
        public void h1() {
            
            //获取一个真实的目标对象
            UserService service = new UserServiceImp();
            
            //代理真实的对象
            ProxyObject proxyObject = new ProxyObject();
            UserService s = (UserService) proxyObject.createProxyWithTarget(service);
        
            User user = new User();
            user.setName("管理员");
            user.setPwd("123");
            s.saveUser(user);
        }
    
    }

    3.执行结果

    调用前====================
    service方法 打印userUser [name=管理员, pwd=123]
    调用后====================
     总结:动态代理可以帮助你在不修改目标对象(或方法)的情况下,实现在目标对象执行某个方法的前、后执行必要的业务逻辑处理。这也是spring框架中实现aop的一种方式。
       
    参考:http://blog.csdn.net/ljt2724960661/article/details/52507314
  • 相关阅读:
    《一个人的村庄》 ——刘亮程
    uva 11020
    Codeforces Round #190 (Div. 2) B. Ciel and Flowers
    hdu3308 线段树——区间合并
    线段树,区间更新
    vim 被墙
    ubuntu12.04 修复Grub2
    windows下mysql数据库忘记密码
    高性能的异步爬虫
    中间件
  • 原文地址:https://www.cnblogs.com/getchen/p/7883587.html
Copyright © 2011-2022 走看看