JDK1.8 动态代理机制及源码解析

本文详细介绍了JDK1.8的动态代理机制,包括静态代理、动态代理(Proxy)、cglib动态代理以及AOP实现原理。重点探讨了JDK1.8动态代理的源码,解析了Proxy类和WeakCache的作用,并展示了动态代理的实际应用示例。
摘要由CSDN通过智能技术生成

静态代理

核心思想:代理对象通过持有需要被代理类的实例,实现代理方式。
参考链接: http://www.cnblogs.com/mengdd/archive/2013/01/30/2883468.html

动态代理

a) jdk 动态代理 Proxy,
核心思想:通过实现被代理类的所有接口,生成一个字节码文件后构造一个代理对象,通过持有反射构造被代理类的一个实例,再通过invoke反射调用被代理类实例的方法,来实现代理。
缺点:被代理类必须实现一个或多个接口
参考链接:http://rejoy.iteye.com/blog/1627405
源码解析:见第四部分

cglib 动态代理

     核心思想:通过生成子类字节码实现,代理类为每个委托方法都生成两个方法,以add方法为例,一个是重写的add方法,一个是CGLIB$add$0方法,该方法直接调用委托类的add方法;
     底层:使用一个小而快的字节码处理框架ASM(Java字节码操控框架),来转换字节码并生成新的类
     缺点:不能代理final修饰的类,
     参考链接:http://blog.csdn.net/yakoo5/article/details/9099133/

AOP实现机制

   a. 实现方式:cglib 和 jdk自带的Proxy实现
   b. 策略:
      1)如果是有接口声明的类进行AOP 时,spring调用的是Java.lang.reflection.Proxy 类来做处理
      2)如果是没有接口声明的类时, spring通过cglib包和内部类来实现
   c.配置:
    <aop:aspectj-autoproxy   proxy-target-class="true"   />配置了这句话的话就会强制使用cglib代理。  默认就是false

JDK动态代理Demo


//业务类接口
public interface MyBusinessInterface{
   
 public void processBusiness();
}

//业务实现类
public class MyBusinessInterfaceImpl implements MyBusinessInterface {
   
 public void processBusiness() {
  System.out.println("processing business.....");
 }
}


//被代理对象调用处理程序,必须实现InvocationHandler接口
public class MyInvocationHandler implements InvocationHandler {
   
    //所代理的真实对象
    private Object target = null;
    //构造器,用于传入所代理的真实对象
    MyInvocationHandler(Object target){
        this.target = target;
    }
    //需要我们实现具体业务的地方
    //proxy:  所生成代理类实例
    //method:  指代的是我们所要调用真实对象的某个方法的Method对象
    //args:  指代的是调用真实对象某个方法时接受的参数
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         System.out.println("You can do something here before process your business");
         //调用目标对象的方法
         Object result = method.invoke(target, args);
        System.out.println("You can do something here after process your business");
        //返回处理结果
        return result;
     }

}

//测试用例
public class Test {
   

 public static void main(String[] args) {
    //被代理真实对象
    MyBusinessInterfaceImpl bpimpl = new MyBusinessInterfaceImpl();
    //被代理对象调用处理程序,需传入被代理对象
    MyInvocationHandler handler = new MyInvocationHandler(bpimpl);
    //生成代理类实例
    MyBusinessInterface bp = (MyBusinessInterface)Proxy.newProxyInstance(bpimpl.getClass().getClassLoader(), bpimpl.getClass().getInterfaces(), handler);
    //调用processBusiness
    bp.processBusiness();
 }
}

JDK1.8动态代理源码解析

Proxy解析


//代理类
public class Proxy implements java.io.Serializable {
    

    private static final long serialVersionUID = -2222568056686623797L;

    //代理类构造函数的参数类型
    private static final Class<?>[] constructorParams =
        { InvocationHandler.class };

    //代理类缓存
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());


    //此代理实例的调用处理程序。
    protected InvocationHandler h;

    private Proxy() {
    }

    //代理类构造函数,参数类型:constructorParams所指定
    protected Proxy(InvocationHandler h) {
        Objects.requireNonNull(h);
        this.h = h;
    }


    //获取目标代理类Class对象,需传入类加载器loader对象和被代理类实现接口数组interfaces随想
      @CallerSensitive
    public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces)
        throws IllegalArgumentException{
         //拷贝接口数组
        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            //校验代理类的访问问权限
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }
        //获取代理类Class对象
        return getProxyClass0(loader, intfs);
    }
     //校验代理类的访问问权限,这一块比较底层,我也不明白
     private static void checkProxyAccess(Class<?> caller, ClassLoader loader, Class<?>... interfaces){
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            //获取调用者类的类加载器
            ClassLoader ccl = caller.getClassLoader();
            if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
            }
            ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
        }
    }
     //获取代理类的Clas对象
     private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        //如果存在给定接口的给定装入器定义的代理类存在,则只返回缓存的副本;
        //否则,它将通过proxyclassfactory创建代理类
        //jdk1.8后收敛到这里 生成代理类字节码过程: ProxyClassFactory中了
        return proxyClassCache.get(loader, interfaces);
    }


    //用于带有0个实现接口的代理类的key键值
    private static final Object key0 = new Object();

    /*
     * Key1 and Key2 are optimized for the common use of dynamic proxies
     * that implement 1 or 2 interfaces.
     */

    /*
     * a key used for proxy class with 1 implemented interface
     */
    //用于带有1个实现接口的代理类的key键值
    private static final class Key1 extends WeakReference<Class<?>> {
    
        private final int hash;

        Key1(Class<?> intf) {
            super(intf);
            this.hash = intf.hashCode();
        }

        @Override
        public int hashCode() {
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            Class<?> intf;
            return this == obj ||
                   obj != null &&
                   obj.getClass() == Key1.class &&
                   (intf = get()) != null &&
                   intf == ((Key1) obj).get();
        }
    }

    // //用于带有2个实现接口的代理类的key键值
    private static final class Key2 exten
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值