JDK动态代理步骤详解(源码分析)

动态代理步骤

1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法

2.创建被代理的类以及接口

3.通过Proxy的静态方法

通过Proxy的静态方法

ProxyObject proxyObject = new ProxyObject();
    InvocationHandler invocationHandler = new DynamicProxy(proxyObject);
    ClassLoader classLoader = proxyObject.getClass().getClassLoader();
    ProxyObjectInterface proxy = (IRoom) Proxy.newProxyInstance(classLoader,new Class[]
    {ProxyObjectInterface.class},invocationHandler);
    proxy.execute();

    public class DynamicProxy implements InvocationHandler {
    private Object object;

    public DynamicProxy(Object object){
        this.object = object;
    }

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

创建一个代理 newProxyInstance

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        //检验h不为空,h为空抛异常
        Objects.requireNonNull(h);
        //接口的类对象拷贝一份
        final Class<?>[] intfs = interfaces.clone();
        //进行一些安全性检查
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }
        /*
         * Look up or generate the designated proxy class.
         *  查询(在缓存中已经有)或生成指定的代理类的class对象。
         */
        Class<?> cl = getProxyClass0(loader, intfs);
        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
            //得到代理类对象的构造函数,这个构造函数的参数由constructorParams指定
            //参数constructorParames为常量值:
            private static final Class<?>[] constructorParams = { InvocationHandler.class };
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            //这里生成代理对象,传入的参数new Object[]{h}后面讲
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

先对h进行判空处理。
这段代码核心就是通过getProxyClass0(loader, intfs)得到代理类的Class对象,然后通过Class对象得到构造方法,进而创建代理对象。下一步看getProxyClass0这个方法。从1可知,先接口得到接口类,当接口的数量超过65535,则报异常。

//此方法也是Proxy类下的方法
    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        // If the proxy class defined by the given loader implementing
        // the given interfaces exists, this will simply return the cached copy;
        // otherwise, it will create the proxy class via the ProxyClassFactory
        //意思是:如果代理类被指定的类加载器loader定义了,并实现了给定的接口interfaces,
        //那么就返回缓存的代理类对象,否则使用ProxyClassFactory创建代理类。
        return proxyClassCache.get(loader, interfaces);
    }

proxyClassCache 是一个弱引用的缓存
这里看到proxyClassCache,有Cache便知道是缓存的意思,正好呼应了前面Look up or generate the designated proxy class。查询(在缓存中已经有)或生成指定的代理类的class对象这段注释。

在进入get方法之前,我们看下 proxyClassCache是什么?高能预警,前方代码看起来可能有乱,但我们只需要关注重点即可。

private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
//K代表key的类型,P代表参数的类型,V代表value的类型。
// WeakCache<ClassLoader, Class<?>[], Class<?>>  proxyClassCache  说明proxyClassCache存的值是Class<?>对象,正是我们需要的代理类对象。
final class WeakCache<K, P, V> {
    private final ReferenceQueue<K> refQueue
        = new ReferenceQueue<>();
    // the key type is Object for supporting null key
    private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
        = new ConcurrentHashMap<>();
    private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
        = new ConcurrentHashMap<>();
    private final BiFunction<K, P, ?> subKeyFactory;
    private final BiFunction<K, P, V> valueFactory;
    public WeakCache(BiFunction<K, P, ?> subKeyFactory,
                     BiFunction<K, P, V> valueFactory) {
        this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
        this.valueFactory = Objects.requireNonNull(valueFactory);
    }

其中map变量是实现缓存的核心变量,他是一个双重的Map结构: (key, sub-key) -> value。其中key是传进来的Classloader进行包装后的对象,sub-key是由WeakCache构造函数传人的KeyFactory()生成的。value就是产生代理类的对象,是由WeakCache构造函数传人的ProxyClassFactory()生成的。如下,回顾一下:

proxyClassCache是个WeakCache类的对象,调用proxyClassCache.get(loader, interfaces); 可以得到缓存的代理类或创建代理类(没有缓存的情况)。

说明WeakCache中有get这个方法。先看下WeakCache类的定义(这里先只给出变量的定义和构造函数),继续看它的get();

//K和P就是WeakCache定义中的泛型,key是类加载器,parameter是接口类数组
public V get(K key, P parameter) {
        //检查parameter不为空
        Objects.requireNonNull(parameter);
         //清除无效的缓存
        expungeStaleEntries();
        // cacheKey就是(key, sub-key) -> value里的一级key,
        Object cacheKey = CacheKey.valueOf(key, refQueue);
        // lazily install the 2nd level valuesMap for the particular cacheKey
        //根据一级key得到 ConcurrentMap<Object, Supplier<V>>对象。如果之前不存在,则新建一个ConcurrentMap<Object, Supplier<V>>和cacheKey(一级key)一起放到map中。
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }

        // create subKey and retrieve the possible Supplier<V> stored by that
        // subKey from valuesMap
        //这部分就是调用生成sub-key的代码,上面我们已经看过怎么生成的了
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        //通过sub-key得到supplier
        Supplier<V> supplier = valuesMap.get(subKey);
        //supplier实际上就是这个factory
        Factory factory = null;

        while (true) {
            //如果缓存里有supplier ,那就直接通过get方法,得到代理类对象,返回,就结束了,一会儿分析get方法。
            if (supplier != null) {
                // supplier might be a Factory or a CacheValue<V> instance
                V value = supplier.get();
                if (value != null) {
                    return value;
                }
            }
            // else no supplier in cache
            // or a supplier that returned null (could be a cleared CacheValue
            // or a Factory that wasn't successful in installing the CacheValue)
            // lazily construct a Factory
            //下面的所有代码目的就是:如果缓存中没有supplier,则创建一个Factory对象,把factory对象在多线程的环境下安全的赋给supplier。
            //因为是在while(true)中,赋值成功后又回到上面去调get方法,返回才结束。
            if (factory == null) {
                factory = new Factory(key, parameter, subKey, valuesMap);
            }

            if (supplier == null) {
                supplier = valuesMap.putIfAbsent(subKey, factory);
                if (supplier == null) {
                    // successfully installed Factory
                    supplier = factory;
                }
                // else retry with winning supplier
            } else {
                if (valuesMap.replace(subKey, supplier, factory)) {
                    // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
                    supplier = factory;
                } else {
                    // retry with current supplier
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }

所以接下来我们看Factory类中的get方法。接下来看supplier的get()

public synchronized V get() { // serialize access
            // re-check
            Supplier<V> supplier = valuesMap.get(subKey);
            //重新检查得到的supplier是不是当前对象
            if (supplier != this) {
                // something changed while we were waiting:
                // might be that we were replaced by a CacheValue
                // or were removed because of failure ->
                // return null to signal WeakCache.get() to retry
                // the loop
                return null;
            }
            // else still us (supplier == this)
            // create new value
            V value = null;
            try {
                 //代理类就是在这个位置调用valueFactory生成的
                 //valueFactory就是我们传入的 new ProxyClassFactory()
                //一会我们分析ProxyClassFactory()的apply方法
                value = Objects.requireNonNull(valueFactory.apply(key, parameter));
            } finally {
                if (value == null) { // remove us on failure
                    valuesMap.remove(subKey, this);
                }
            }
            // the only path to reach here is with non-null value
            assert value != null;

            // wrap value with CacheValue (WeakReference)
            //把value包装成弱引用
            CacheValue<V> cacheValue = new CacheValue<>(value);

            // put into reverseMap
            // reverseMap是用来实现缓存的有效性
            reverseMap.put(cacheValue, Boolean.TRUE);

            // try replacing us with CacheValue (this should always succeed)
            if (!valuesMap.replace(subKey, this, cacheValue)) {
                throw new AssertionError("Should not reach here");
            }

            // successfully replaced us with new CacheValue -> return the value
            // wrapped by it
            return value;
        }
    }

拨云见日,来到ProxyClassFactory的apply方法,代理类就是在这里生成的。

首先看proxyClassCache的定义WeakCache<ClassLoader, Class<?>[], Class<?>>,泛型里面第一个表示加载器K,第二个表示接口类P,第三个则是生成的代理类V。而V的生成则是通过ProxyClassFactory生成的。调用其apply();

//这里的BiFunction<T, U, R>是个函数式接口,可以理解为用T,U两种类型做参数,得到R类型的返回值
private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    {
        // prefix for all proxy class names
        //所有代理类名字的前缀
        private static final String proxyClassNamePrefix = "$Proxy";
        // next number to use for generation of unique proxy class names
        //用于生成代理类名字的计数器
        private static final AtomicLong nextUniqueNumber = new AtomicLong();
        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            //验证代理接口,可不看
            for (Class<?> intf : interfaces) {
                /*
                 * Verify that the class loader resolves the name of this
                 * interface to the same Class object.
                 */
                Class<?> interfaceClass = null;
                try {
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
                if (interfaceClass != intf) {
                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }
                /*
                 * Verify that the Class object actually represents an
                 * interface.
                 */
                if (!interfaceClass.isInterface()) {
                    throw new IllegalArgumentException(
                        interfaceClass.getName() + " is not an interface");
                }
                /*
                 * Verify that this interface is not a duplicate.
                 */
                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                    throw new IllegalArgumentException(
                        "repeated interface: " + interfaceClass.getName());
                }
            }
            //生成的代理类的包名
            String proxyPkg = null;     // package to define proxy class in
            //代理类访问控制符: public ,final
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
            /*
             * Record the package of a non-public proxy interface so that the
             * proxy class will be defined in the same package.  Verify that
             * all non-public proxy interfaces are in the same package.
             */
            //验证所有非公共的接口在同一个包内;公共的就无需处理
            //生成包名和类名的逻辑,包名默认是com.sun.proxy,
            // 类名默认是$Proxy 加上一个自增的整数值
            //如果被代理类是 non-public proxy interface ,则用和被代理类接口一样的包名
            for (Class<?> intf : interfaces) {
                int flags = intf.getModifiers();
                if (!Modifier.isPublic(flags)) {
                    accessFlags = Modifier.FINAL;
                    String name = intf.getName();
                    int n = name.lastIndexOf('.');
                    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
                    if (proxyPkg == null) {
                        proxyPkg = pkg;
                    } else if (!pkg.equals(proxyPkg)) {
                        throw new IllegalArgumentException(
                            "non-public interfaces from different packages");
                    }
                }
            }
            if (proxyPkg == null) {
                // if no non-public proxy interfaces, use com.sun.proxy package
                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
            }

            /*
             * Choose a name for the proxy class to generate.
             */
            long num = nextUniqueNumber.getAndIncrement();
            //代理类的完全限定名,如com.sun.proxy.$Proxy0.calss
            String proxyName = proxyPkg + proxyClassNamePrefix + num;

            /*
             * Generate the specified proxy class.
             */
            //核心部分,生成代理类的字节码
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                //把代理类加载到JVM中,至此动态代理过程基本结束了
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                /*
                 * A ClassFormatError here means that (barring bugs in the
                 * proxy class generation code) there was some other
                 * invalid aspect of the arguments supplied to the proxy
                 * class creation (such as virtual machine limitations
                 * exceeded).
                 */
                throw new IllegalArgumentException(e.toString());
            }
        }
    }

然后调用getMethod(),将equals(),hashcode(),toString()等方法添加进去。然后遍历所有接口的方法,添加到代理类中。最后将这些方法进行排序。

private static List<Method> getMethods(Class<?>[] interfaces) {
        List<Method> result = new ArrayList<Method>();
        try {
            result.add(Object.class.getMethod("equals", Object.class));
            result.add(Object.class.getMethod("hashCode", EmptyArray.CLASS));
            result.add(Object.class.getMethod("toString", EmptyArray.CLASS));
        } catch (NoSuchMethodException e) {
            throw new AssertionError();
        }

        getMethodsRecursive(interfaces, result);
        return result;
    }
private static void getMethodsRecursive(Class<?>[] interfaces, List<Method> methods) {
        for (Class<?> i : interfaces) {
            getMethodsRecursive(i.getInterfaces(), methods);
            Collections.addAll(methods, i.getDeclaredMethods());
        }
    }

最后输出相关proxy class

package com.zhb.jdk.proxy;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Proxy;

import com.zhb.jdk.dynamicProxy.HelloworldImpl;

import sun.misc.ProxyGenerator;

/**
 * @author ZHB
 * @date 2018年8月31日下午11:35:07
 * @todo TODO
 */
public class DynamicProxyTest {

    public static void main(String[] args) {

        IUserService target = new UserServiceImpl();
        MyInvocationHandler handler = new MyInvocationHandler(target);
        //第一个参数是指定代理类的类加载器(我们传入当前测试类的类加载器)
        //第二个参数是代理类需要实现的接口(我们传入被代理类实现的接口,这样生成的代理类和被代理类就实现了相同的接口)
        //第三个参数是invocation handler,用来处理方法的调用。这里传入我们自己实现的handler
        IUserService proxyObject = (IUserService) Proxy.newProxyInstance(DynamicProxyTest.class.getClassLoader(),
                target.getClass().getInterfaces(), handler);
        proxyObject.add("陈粒");

        String path = "D:/$Proxy0.class";
        byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", HelloworldImpl.class.getInterfaces());
        FileOutputStream out = null;

        try {
            out = new FileOutputStream(path);
            out.write(classFile);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space

import com.zhb.jdk.proxy.IUserService;
import java.lang.reflect.*;

public final class $Proxy0 extends Proxy
    implements IUserService
{

    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;
    //代理类的构造函数,其参数正是是InvocationHandler实例,
    //Proxy.newInstance方法就是通过通过这个构造函数来创建代理实例的
    public $Proxy0(InvocationHandler invocationhandler)
    {
        super(invocationhandler);
    }
     // Object类中的三个方法,equals,toString, hashCode
    public final boolean equals(Object obj)
    {
        try
        {
            return ((Boolean)super.h.invoke(this, m1, new Object[] {
                obj
            })).booleanValue();
        }
        catch (Error ) { }
        catch (Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final String toString()
    {
        try
        {
            return (String)super.h.invoke(this, m2, null);
        }
        catch (Error ) { }
        catch (Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }
    //接口代理方法
    public final void add(String s)
    {
        try
        {
            // invocation handler的 invoke方法在这里被调用
            super.h.invoke(this, m3, new Object[] {
                s
            });
            return;
        }
        catch (Error ) { }
        catch (Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    public final int hashCode()
    {
        try
        {
            // 在这里调用了invoke方法。
            return ((Integer)super.h.invoke(this, m0, null)).intValue();
        }
        catch (Error ) { }
        catch (Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

    // 静态代码块对变量进行一些初始化工作
    static
    {
        try
        {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
                Class.forName("java.lang.Object")
            });
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m3 = Class.forName("com.zhb.jdk.proxy.IUserService").getMethod("add", new Class[] {
                Class.forName("java.lang.String")
            });
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
        }
        catch (NoSuchMethodException nosuchmethodexception)
        {
            throw new NoSuchMethodError(nosuchmethodexception.getMessage());
        }
        catch (ClassNotFoundException classnotfoundexception)
        {
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());
        }
    }
}

以上就是JDK动态代理步骤详解(源码分析)的详细内容,更多关于JDK动态代理的资料请关注我们其它相关文章!

(0)

相关推荐

  • Spring AOP注解失效的坑及JDK动态代理

    @Transactional @Async等注解不起作用 之前很多人在使用Spring中的@Transactional, @Async等注解时,都多少碰到过注解不起作用的情况. 为什么会出现这些情况呢?因为这些注解的功能实际上都是Spring AOP实现的,而其实现原理是通过代理实现的. JDK动态代理 以一个简单的例子理解一下JDK动态代理的基本原理: //目标类接口 public interface JDKProxyTestService { void run(); } //目标类 publ

  • Java JDK动态代理(AOP)的实现原理与使用详析

    本文主要给大家介绍了关于Java JDK动态代理(AOP)实现原理与使用的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式UML图: 简单结构示意图: 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别.通过代理类这中间一层,能有效控制对委托类对

  • jdk中动态代理异常处理分析:UndeclaredThrowableException

    背景 在RPC接口调用场景或者使用动态代理的场景中,偶尔会出现UndeclaredThrowableException,又或者在使用反射的场景中,出现InvocationTargetException,这都与我们所期望的异常不一致,且将真实的异常信息隐藏在更深一层的堆栈中.本文将重点分析下UndeclaredThrowableException 先给结论 使用jdk动态代理接口时,若方法执行过程中抛出了受检异常但方法签名又没有声明该异常时则会被代理类包装成UndeclaredThrowableE

  • 详解Spring的两种代理方式:JDK动态代理和CGLIB动态代理

    代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为"代理",所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用 A. 抽象主题角色 声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以是使用代理主题 B. 代理主题(Proxy)角色: 代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象:代理主题角

  • JDK动态代理与CGLib动态代理的区别对比

    案例: public interface ForumService { void removeTopic(int topicId); void removeForum(int forumId); } 对相关方法进行性能监控 public class ForumServiceImpl implements ForumService { public void removeTopic(int topicId) { // PerformanceMonitor.begin("com.hand.proxy

  • java jdk动态代理详解

    jdk动态代理要对一个类进行代理,被代理的类必须实现至少一个接口,并且只有接口中的方法才能被代理. jdk实现动态代理一般分为三步: 1. 编写接口和实现类. 2. 写一个处理器,该处理器实现InvocationHandler接口,该接口只有一个方法,其签名为public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;可在该处理器的实现方法中,在方法调用前和调用后加入自己的代码,从而进行动态拦截

  • JDK动态代理步骤详解(源码分析)

    动态代理步骤 1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法 2.创建被代理的类以及接口 3.通过Proxy的静态方法 通过Proxy的静态方法 ProxyObject proxyObject = new ProxyObject(); InvocationHandler invocationHandler = new DynamicProxy(proxyObject); ClassLoader classLoader = proxyObject.getCl

  • Java静态代理与动态代理案例详解

    代理模式 代理模式(Proxy):为其他对象提供一个代理以控制对这个对象的访问. 主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上.在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层. 代理模式的元素是:共同接口.代理对象.目标对象. 代理模式的行为:由代理对象执行目标对象的方法.由代理对象扩展目标对象的方法. 代理模式的

  • Java基础之动态代理Cglib详解

    一.前言 经测试,jdk创建对象的速度远大于cglib,这是由于cglib创建对象时需要操作字节码.cglib执行速度略大于jdk,所以比较适合单例模式.另外由于CGLIB的大部分类是直接对Java字节码进行操作,这样生成的类会在Java的永久堆中.如果动态代理操作过多,容易造成永久堆满,触发OutOfMemory异常.spring默认使用jdk动态代理,如果类没有接口,则使用cglib. 二.服务 package proxy.cglib; /** * @Description: <br/>

  • Spring静态代理和动态代理代码详解

    本节要点: Java静态代理 Jdk动态代理 1 面向对象设计思想遇到的问题 在传统OOP编程里以对象为核心,并通过对象之间的协作来形成一个完整的软件功能,由于对象可以继承,因此我们可以把具有相同功能或相同特征的属性抽象到一个层次分明的类结构体系中.随着软件规范的不断扩大,专业化分工越来越系列,以及OOP应用实践的不断增多,随之也暴露了一些OOP无法很好解决的问题. 现在假设系统中有三段完全相似的代码,这些代码通常会采用"复制"."粘贴"方式来完成,通过这种方式开发

  • Spring AOP里的静态代理和动态代理用法详解

    什么是代理? 为某一个对象创建一个代理对象,程序不直接用原本的对象,而是由创建的代理对象来控制原对象,通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间 什么是静态代理? 由程序创建或特定工具自动生成源代码,在程序运行前,代理类的.class文件就已经存在 通过将目标类与代理类实现同一个接口,让代理类持有真实类对象,然后在代理类方法中调用真实类方法,在调用真实类方法的前后添加我们所需要的功能扩展代码来达到增强的目的. 优点

  • Java动态代理机制详解_动力节点Java学院整理

    class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息,生成对应的 Class对象: class字节码文件是根据JVM虚拟机规范中规定的字节码组织规则生成的.具体class文件是怎样组织类信息的,可以参考 此博文:深入理解Java Class文件格式系列.或者是Java虚拟机规范. 下面通过一段代

  • Java反射(JDK)与动态代理(CGLIB)详解

    目录 一.反射 二.动态代理 1.JDK代理 2.CGLIB代理 3.JDK代理与CGLIB代理对比 总结 一.反射 概念:在运行状态中,对于任意的一个类,都能够知道这个类的所有字段和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法 实现方法:JVM在第一次加载某个类时会生成一个Class对象,里面记录了这个类的信息 链接:类加载机制(留坑) 二.动态代理 动态代理的作用:在不改变原代码的基础上增加新的功能,如日志.权限检验等 反射在动态代理中的应用:由于知道原类的字段.方法等信息,才

  • Spring BPP中如何优雅的创建动态代理Bean详解

    v一.前言 本文章所讲并没有基于Aspectj,而是直接通过Cglib以及ProxyFactoryBean去创建代理Bean.通过下面的例子,可以看出Cglib方式创建的代理Bean和ProxyFactoryBean创建的代理Bean的区别. v二.基本测试代码 测试实体类,在BPP中创建BppTestDepBean类型的代理Bean. @Component public static class BppTestBean { @Autowired private BppTestDepBean d

  • java代理模式与动态代理模式详解

    1.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 生活中的例子:过年加班比较忙,没空去买火车票,这时可以打个电话到附近的票务中心,叫他们帮你买张回家的火车票,当然这会附加额外的劳务费.但要清楚票务中心自己并不卖票,只有火车站才真正卖票,票务中心卖给你的票其实是通过火车站实现的.这点很重要!

  • Mybatis实现Mapper动态代理方式详解

    一.实现原理 Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法. Mapper接口开发需要遵循以下规范: 1.Mapper.xml文件中的namespace与mapper接口的类路径相同. 2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 3.Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的para

随机推荐