动态代理

动态代理是指,程序在整个运行的过程中根本不存在目标的代理类,目标对象的代理对象只是由代理生成工具(不是真是定义的类)在程序运行时由JVM 根据反射等机制动态生成的。代理对象与目标对象的代理关系在程序运行时才确定。

1. JDK动态代理

动态代理的实现方式常用的有两种:使用JDK 的Proxy,与通过CGLIB生成代理。JDK的动态要求目标对象必须实现接口,这是java设计上的要求。从jdk1.3以来,java语言通过java.lang.reflect包提供的三个类支持代理模式Proxy,Method和InvocationHandler.

2. CGLIB动态代理

CGLIB(Code Generation Library)是一个开源项目。是一个强大的,高性能,高质量的Code生成的类库,它可以在运行期扩展java类与实现java接口。它广泛的被许多AOP 的框架使用。如:Spring AOP.
使用 JDK 的 Proxy 实现代理,要求目标类与代理实现相同的接口。若目标类不存在接口,则无法实现该方式。但对于无接口的类,要为其创建动态代理,就要使用CGLIB来实现。

3. 动态代理的作用

1)在目标类源代码不改变的情况下,增强gongneng。
2)减少代码的重复。
3)专注业务逻辑代码。
4)解耦合,让你的业务功能和日志,事务和非业务功能分离。

应用代码

  1. 创建目标类
    动态代理_程序运行

  2. 创建InvocationHanler接口的实现类,在这个类实现给目标方法增强功能。

package org.example.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class UserDaoEnhance implements InvocationHandler {
    //目标对象
    Object target = null;

    public UserDaoEnhance(Object target) {
        this.target = target;
    }

    //通过代理对象执行方法时,会调用这个invoke方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("执行前增强.....");
        //执行目标类方法,通过Method类实现
        Object result = method.invoke(target, args);
        System.out.println("执行后增强.....");
        //目标方法的执行结果
        return result;
    }
}

  1. 使用JDK中类Proxy,创建代理对象,实现创建对象的能力。
@Test
    public void test4(){
        //创建目标对象
        UserDao target = new UserDaoImpl();
        //创建InvocationHandler对象
        InvocationHandler handler = new UserDaoEnhance(target);
        //使用Proxy创建代理
        UserDao userDao = (UserDao) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
        //通过代理执行方法,调用handler中的invoke方法
        userDao.run();
    }