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
原文地址:https://www.cnblogs.com/getchen/p/7883587.html