了解代理模式这一篇文章就够了( 二 )


代码实现JDK代理
目标对象需要实现的接口
public interface TargetInterface {void method();}目标对象
public class TargetObject implements TargetInterface {@Overridepublic void method() {System.out.println("被代理的类中的方法执行了!");}}代理工厂
public class ProxyFactory {// 目标对象private Object target;// 构造器public ProxyFactory(Object target) {this.target = target;}// 通过JDK的API在内存中动态生成一个代理对象 。public Object getProxyInstance() {/*** 参数介绍* ClassLoader loader:目标对象的类加载器* Class[] interfaces:目标对象实现的接口* InvocationHandler h:事件处理器 。 执行目标对象的方法时 ,*会触发该处理器中的invoke方法 。*/return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),/*** 此处用到了java8的Lambda表达式 。 看不太懂的有可以用传统方式 。* 传统方式:new InvocationHandler() { // 重写invoke方法 }** 参数说明:* Object proxy:代理类的实例* Method method:目标对象方法* Object[] args:目标对象方法入参*/(proxy, method, args) -> {System.out.println("JDK动态代理开始!");// 执行目标类的方法 。 returnVal是方法的返回值 , 没有返回值时为空 。Object returnVal = method.invoke(target, args);System.out.println("JDK动态代理结束!");return returnVal;});}}客户端测试类
public class Client {public static void main(String[] args) {TargetObject targetObject = new TargetObject();ProxyFactory proxyFactory = new ProxyFactory(targetObject);// 注意:此处强转的类型只能是目标类实现的接口类型!!!TargetInterface proxyInstance = (TargetInterface) proxyFactory.getProxyInstance();proxyInstance.method();}}执行结果
了解代理模式这一篇文章就够了文章插图
总结
优点:使用JDK动态代理 , 可以将代理类的创建推迟到运行时期在内存中创建 , 这样就可以大大减少代理类的创建和维护 。
缺点:目标类必须实现接口 , 还增加了代码的理解难度 。
Cglib代理基本介绍以及注意事项
1、使用Cglib进行动态代理的目标类不需要强制要求实现接口 。 2、Cglib代理也叫做子类代理 , 它是在内存中动态的创建一个目标类的子类对象从而实现对目标类的代理 。 Cglib代理也是属于动态代理的一种 。 3、Cglib是一个强大的高性能代码生成工具 , 它可以在程序运行时期扩展类与实现接口 。 许多AOP框架都有使用Cglib 。 4、Cglib的底层是通过字节码处理框架ASM来转换字节码并生成新类的 。 5、注意:使用Cglib代理的类不能是final修饰的 , 并且被代理类中final和static修饰的方法不会被代理 。
Cglib代理UML类图
了解代理模式这一篇文章就够了文章插图
示例代码
目标对象
public class TargetObject {public void method() {System.out.println("被代理的类中的方法执行了!");}}代理工厂
public class ProxyFactory implements MethodInterceptor {// 目标对象private Object target;// 构造方法public ProxyFactory(Object target) {this.target = target;}// 创建目标对象public Object getProxyInstance() {// 创建一个工具类Enhancer enhancer = new Enhancer();// 设置父类enhancer.setSuperclass(target.getClass());// 设置回调函数enhancer.setCallback(this);// 创建代理对象return enhancer.create();}/*** 重写intercept , 完成对目标对象中方法的扩展** 参数介绍:*Object o:cglib动态生成的对象 。*Method method:目标类中的方法 。*Object[] objects:方法的参数 。*MethodProxy methodProxy:根据目标类的方法生成的代理方法 。*/@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)throws Throwable {System.out.println("Cglib代理模式开始!");/*** invoke方法入参说明:*Object obj:方法所对应的类的对象 , 在该代码示例中指的就是目标类 。*Object... args:方法的入参 。*/Object invokeValue = http://kandian.youth.cn/index/method.invoke(target, objects);System.out.println("Cglib代理模式结束!");return invokeValue;}}