欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

jdk和cglib动态代理

程序员文章站 2022-06-17 20:22:06
...

静态代理和动态代理

  • 静态代理:代理类在编译期已经存在在.class文件中。
  • 动态代理:程序运行时,通过反射机制动态创建而成。
  • 如果需要为不同的主题类提供代理,需要一一增加代理类,导致类个数急剧增加,所以需要在运行时创建动态代理。

动态代理

原理

  • jdk动态代理需要主题类实现接口,使用实现相同接口的代理类代理主题类。如果主题类没有实现接口,则需要使用cglib动态代理。
  • cglib使用继承实现代理,针对指定的类创建一个子类,覆盖其中的方法实现增强。无法对final代理。

jdk

  • jdk动态代理通过Proxy和InvocationHandler接口实现。
  • Proxy:提供创建动态代理类和对象的方法。
    public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException

    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
  • InvocationHandler:实现增强的业务逻辑。
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
  • 实例。
    jdk和cglib动态代理
public class DaoHandler implements InvocationHandler {

    private Object subject;

    public DaoHandler(Object subject) {
        this.subject = subject;
    }

    public DaoHandler() {
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        beforeInvoke();
        Object result = method.invoke(subject, args);
        afterInvoke();
        return result;
    }

    private void beforeInvoke() {
        System.out.println("beforeInvoke");
    }

    private void afterInvoke() {
        System.out.println("afterInvoke");
    }
}

public class Client {

    public static void main(String[] args) {
        AbstractUserDao userDao = new UserDao();
        InvocationHandler handler = new DaoHandler(userDao);

        AbstractUserDao proxy = (AbstractUserDao) Proxy
                .newProxyInstance(AbstractUserDao.class.getClassLoader(), new Class[]{AbstractUserDao.class}, handler);

        System.out.println(proxy.findUser(""));
    }
}

cglib

  • cglib动态代理通过Enhancer和MethodInterceptor接口实现。
  • Enhancer:创建代理对象。
    public Object create() 
  • MethodInterceptor:实现增强的业务逻辑。
    Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
  • 实例。
    jdk和cglib动态代理
public class UserDaoProxyHandler implements MethodInterceptor {

    private Object subject;

    public UserDaoProxyHandler(Object subject) {
        this.subject = subject;
    }

    public UserDaoProxyHandler() {
    }

    public Object getInstance() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.subject.getClass());
        //设置回调方法
        enhancer.setCallback(this);
        //创建代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        beforeInvoke();
        Object result = methodProxy.invokeSuper(o, objects);
        afterInvoke();
        return result;
    }


    private void beforeInvoke() {
        System.out.println("beforeInvoke");
    }

    private void afterInvoke() {
        System.out.println("afterInvoke");
    }
}

public class Client {

    public static void main(String[] args) {
        UserDao userDao = new UserDao();
        UserDao proxy = (UserDao) new UserDaoProxyHandler(userDao).getInstance();

        System.out.println(proxy.findUser(""));
    }
}