Le mode proxy de la première partie du proxy dynamique spring-aop-JDK

Pour compenser les lacunes des agents statiques susceptibles de produire des explosions de classe, des opérations d'agent dynamique voient le jour. Le proxy dynamique JDK ne peut que l'interface proxy (car la classe proxy générée par le proxy dynamique a hérité du proxy, donc elle ne peut que l'interface proxy)

Quelles sont les étapes pour implémenter le proxy dynamique JDK?

1. Créez une nouvelle interface et créez une nouvelle classe d'implémentation (appelée targetObject dans le proxy dynamique JDK)

2. La nouvelle classe proxy implémente l'interface InvocationHandler pour remplacer la méthode invoke

Prenons d'abord une photo simple, ne vaporisez pas si vous ne l'aimez pas

S'il vous plaît voir la démo de code ci-dessous

public interface UserDao {

    void query(String id);

    void insert(int id,String name);
}

public class UserDaoImpl implements  UserDao {
    @Override
    public void query(String id) {
        System.out.println("query db --id:"+id);
    }

    @Override
    public void insert(int id, String name) {
        System.out.println("insert db --id:"+id+"--name:"+name);
    }
}


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

public class UserDaoProxy implements InvocationHandler {

    UserDao target;//目标对象UserDaoImpl

    public UserDaoProxy(UserDao target){
        this.target = target;
    }


    public Object getInstance(){//通过Proxy对象 根据 目标对象 创建其 代理对象
        Object object = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        return  object;
    }

    //proxy 代理对象 即 $Proxy0 
    //targetMethod 目标对象的query,insert方法 
    //targetArgs 目标对象的参数 [110] , [1,222]
    @Override
    public Object invoke(Object proxy, Method targetMethod, Object[] targetArgs) throws Throwable {
        sout("aop before......")
        return targetMethod.invoke(target,targetArgs);
        sout("aop after......")
    }
}


public class Test {
    public static void main(String[] args) {
        //目标对象
        UserDao target = new UserDaoImpl();
        //代理类对象
        UserDaoProxy proxyClass = new UserDaoProxy(target);
        //代理对象
        UserDao Proxy =(UserDao) proxyClass.getInstance();

        Proxy.query("110");
        Proxy.insert(1,"222");
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
    }
}

Implémenter le programme de débogage de l'interface InvocationHandler (code non source)

Il y a 2 objets ici, à savoir l'objet cible cible UserDaoImpl

proxyClass Méthode de génération d'objet proxy et objet cible d'exécution de proxy

Allons voir le troisième objet proxy. Cet objet proxy doit commencer par $ Proxy

 

Trois objets ici

Le premier est l'objet de classe de la classe actuelle, c'est-à-dire que l'objet de classe proxy est le proxyClass = UserDaoProxy @ 626 dans la figure ci-dessus

Le deuxième objet objet = {$ Proxy0 @ 657} Cet objet est l'objet proxy retourné commençant par $ Proxy

Le troisième objet est la cible de l'objet proxy, qui est la cible = UserDaoImpl @ 623 dans la figure ci-dessus

Continuez à regarder en arrière et voyez que l'objet proxy retourné est le début du $ Proxy

System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

Grâce à cette ligne de code, nous pouvons voir l'objet proxy $ Proxy0 créé par la couche inférieure pour nous, et nous pouvons savoir pourquoi nous ne pouvons que proxy de l'interface, car la syntaxe Java limite idéalement un seul héritage

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.sun.proxy;

import com.dao.UserDao;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements UserDao {
    private static Method m1;
    private static Method m4;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void query(String var1) throws  {
        try {
            super.h.invoke(this, m4, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void insert(int var1, String var2) throws  {
        try {
            super.h.invoke(this, m3, new Object[]{var1, var2});
        } catch (RuntimeException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m4 = Class.forName("com.dao.UserDao").getMethod("query", Class.forName("java.lang.String"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.dao.UserDao").getMethod("insert", Integer.TYPE, Class.forName("java.lang.String"));
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

 

Voyons comment la couche inférieure du proxy dynamique jdk nous aide à atteindre

Mettre à jour ce vendredi

Je suppose que tu aimes

Origine blog.csdn.net/qq_38108719/article/details/100003709
conseillé
Classement