网站开发搭建,动画设计策划案,柳州网站推广,免费看行情的软件大全下载JDK1.6中的动态代理 在Java中Java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口#xff0c;通过使用这个类和接口可以生成一个动态代理对象。JDK提供的代理只能针对接口做代理 java.lang.reflect.Proxy 提供用于创建动态代理类和实例的静态方法#xff0c;…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 {Overridepublic int add(int i, int j) {int result i j;System.out.println(addresult);return result;}Overridepublic int sub(int i, int j) {int result i - j;System.out.println(subresult);return result;}Overridepublic int mul(int i, int j) {int result i * j;System.out.println(mulresult);return result;}Overridepublic int div(int i, int j) {int result i / j;System.out.println(divresult);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.targettarget;}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,InvocationTargetExceptionSystem.out.println(method.getName()方法前置。。。。。。。。。。。。。。。。);Object resultmethod.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 acnew ArithmeticCalculatorImpl();//Object proxyProxy.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(); } Overridepublic 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 cglibnew CglibProxy(); ArithmeticCalculatorImpl bookCglib(ArithmeticCalculatorImpl)cglib.getInstance(new ArithmeticCalculatorImpl()); bookCglib.add(10, 30);}
} CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少但是CGLib在创建代理对象时所花费的时间却比JDK多得多所以对于单例的对象因为无需频繁创建对象用CGLib合适反之使用JDK方式要更为合适一些。转载于:https://www.cnblogs.com/jalja/p/6514829.html