JAVA动态代理

简介:

JDK1.6中的动态代理

在Java中Java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口可以生成一个动态代理对象。JDK提供的代理只能针对接口做代理

java.lang.reflect.Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

// 方法 1: 该方法用于获取指定代理对象所关联的调用处理器public static InvocationHandler getInvocationHandler(Object proxy) 

// 方法 2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象public static Class<?> getProxyClass(ClassLoader loader, 
Class<?>... interfaces)// 方法 3:该方法用于判断指定类对象是否是一个动态代理类public static boolean isProxyClass(Class<?> cl) 

// 方法 4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例public static Object newProxyInstance(ClassLoader loader,
 Class<?>[] interfaces,InvocationHandler h)

java.lang.reflect.InvocationHandler:调用处理器接口,自定义invokle方法,用于实现对于真正委托类的代理访问。

/**
 该方法负责集中处理动态代理类上的所有方法调用。
 第一个参数既是代理类实例,
 第二个参数是被调用的方法对象(反射中Method对象)
 第三个参数是调用方法的参数列表。
 调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行*/public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;

 使用Proxy类中的newProxyInstance方法创建代理对象

参数:
        loader - 定义代理类的类加载器
        interfaces - 代理类要实现的接口列表
        h - 指派方法调用的调用处理程序 
        返回: 一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口 
        public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException

实例

接口:

package com.jalja.org.base.poxy;public interface ArithmeticCalculator {    int add(int i, int j);    int sub(int i, int j);    int mul(int i, int j);    int div(int i, int j);
}

实现类:

package com.jalja.org.base.poxy;public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
    @Override    public int add(int i, int j) {        int result = i + j;
        System.out.println("add:"+result);        return result;
    }
    @Override    public int sub(int i, int j) {        int result = i - j;
        System.out.println("sub:"+result);        return result;
    }
    @Override    public int mul(int i, int j) {        int result = i * j;
        System.out.println("mul:"+result);        return result;
    }
    @Override    public int div(int i, int j) {        int result = i / j;
        System.out.println("div:"+result);        return result;
    }
}

代理类及使用:

package com.jalja.org.base.poxy.test;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import com.jalja.org.base.poxy.ArithmeticCalculator;import com.jalja.org.base.poxy.ArithmeticCalculatorImpl;public class MyInvocationHandler implements InvocationHandler{    private Object target;//目标对象(对哪个对象做动态代理)
    public MyInvocationHandler(Object target) {        this.target=target;
    }
    @Override    /**
     * proxy - 在其上调用方法的代理实例
     * method - 对应于在代理实例上调用的接口方法的 Method 实例。Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。
     * args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中。 
     * return - 返回代理对象     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        //obj - 从中调用底层方法的对象        //args - 用于方法调用的参数 
        //public Object invoke(Object obj, Object... args)throws IllegalAccessException, IllegalArgumentException,InvocationTargetException
        System.out.println(method.getName()+"方法前置。。。。。。。。。。。。。。。。");
        Object result=method.invoke(target, args);
        System.out.println("method:"+method);
        System.out.println(method.getName()+"方法后置。。。。。。。。。。。。。。。。");        return result;
    }    public static void main(String[] args) {        /*参数:
        loader - 定义代理类的类加载器
        interfaces - 代理类要实现的接口列表
        h - 指派方法调用的调用处理程序 
        返回: 一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口 
        public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException*/
        ArithmeticCalculator ac=new ArithmeticCalculatorImpl();        //Object proxy=Proxy.newProxyInstance(ac.getClass().getClassLoader(), ac.getClass().getInterfaces(), new MyInvocationHandler(ac));
        ArithmeticCalculator proxy=(ArithmeticCalculator)Proxy.newProxyInstance(
                ac.getClass().getClassLoader(), ac.getClass().getInterfaces(), new MyInvocationHandler(ac));
        proxy.add(10, 100);
        proxy.sub(20, 10);
    }

}

Cglib动态代理 
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

 Demo:

package com.jalja.org.base.poxy.Cglib;import java.lang.reflect.Method;import com.jalja.org.base.poxy.ArithmeticCalculatorImpl;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class CglibProxy implements MethodInterceptor{    private Object target;  
    /** 
     * 创建代理对象 
     * @param target 
     * @return 
     */  
    public Object getInstance(Object target) {  
        this.target = target;  
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(this.target.getClass());  
        // 回调方法  
        enhancer.setCallback(this);  
        // 创建代理对象  
        return enhancer.create();  
    }  
    @Override    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("前置代理");  
        //通过代理类调用父类中的方法  
        Object result = proxy.invokeSuper(obj, args);  
        System.out.println("后置代理");  
        return result;  
    }    public static void main(String[] args) {
       CglibProxy cglib=new CglibProxy();  
       ArithmeticCalculatorImpl bookCglib=(ArithmeticCalculatorImpl)cglib.getInstance(new ArithmeticCalculatorImpl());  
       bookCglib.add(10, 30);
    }
}













本文转自xsster51CTO博客,原文链接:http://blog.51cto.com/12945177/1950755 ,如需转载请自行联系原作者




相关文章
|
4月前
|
缓存 安全 Java
Java中动态代理使用与原理详解
Java中动态代理使用与原理详解
53 0
|
4月前
|
Java
Java之动态代理的详细解析
2. 动态代理 2.1 好处: 无侵入式的给方法增强功能 2.2 动态代理三要素: 1,真正干活的对象
38 0
|
4月前
|
Java
【Java动态代理】—— 每天一点小知识
【Java动态代理】—— 每天一点小知识
|
5月前
|
Arthas Dubbo Java
Alibaba Java诊断工具Arthas查看Dubbo动态代理类
Alibaba Java诊断工具Arthas查看Dubbo动态代理类
54 0
|
5天前
|
监控 Java 开发者
掌握 Java 反射和动态代理
【4月更文挑战第19天】Java反射和动态代理提供强大功能和灵活性。反射允许运行时检查和操作类,获取类信息、动态调用方法,但可能带来性能损失和降低代码可读性。动态代理则用于创建代理对象,实现透明性和横切关注点分离,常用于日志、权限检查等。两者结合能实现更复杂功能。掌握这些技术能提升代码的灵活性和可扩展性,但也需注意性能和可读性。通过学习和实践,能更好地构建高效软件系统。
|
1月前
|
Java API 开发者
Java代理模式——静态代理与动态代理
Java代理模式——静态代理与动态代理
27 1
|
1月前
|
监控 Java 程序员
java的动态代理如何实现
java的动态代理如何实现
24 0
|
2月前
|
设计模式 Java 程序员
Java动态代理
Java动态代理详解
|
2月前
|
Java
Java动态代理简易说明
Java动态代理简易说明
10 0
|
2月前
|
设计模式 Java API
[Java]静态代理、动态代理(基于JDK1.8)
本篇文章主要是对静态代理和动态代理实现思路的简述,以示例为主,少涉及理论。 如果文中阐述不全或不对的,多多交流。
54 1
[Java]静态代理、动态代理(基于JDK1.8)