java基础——代理模式

使用场景:

保护目标对象 增强目标对象 降低系统的耦合度 易于扩展

特点:

jdk动态代理被代理对象必须实现一个接口

实现方式:
  1. 静态代理
  2. 动态代理:jdk动态代理、cglib动态代理
jdk动态代理
package com.wh.proxy;

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

public class JDKProxy implements InvocationHandler {

    private Object target;

    public Object getInstance(Object target) throws Exception{
        this.target = target;
        Class<?> clazz = target.getClass();
        //1.newProxyInstance做了什么操作,传入三个参数的意义
        return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before ();
        //2.method是什么方法、返回的是什么对象
        Object invoke = method.invoke(this.target, args);
        after();
        return invoke;
    }

    private void before(){
        System.out.println("前置方法!");
    }

    private void after(){
        System.out.println("后置方法!");
    }
}

总结:首先jdk动态代理实现了invocationhandler接口实现了invoke方法
1.proxy相当于是一个工具类,用来生成一个代理类并存储在缓存中,该继承了proxy实现了被代理对象的接口,只有一个有参传入invocationghandler对象的构造器;
2.invoke方法是在执行内存中生成的代理类的方法里执行的

1.jdk动态代理使用的一个工具类:Proxy.newProxyInstance()
public class Proxy implements java.io.Serializable {
    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() {
    }

	public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {

        Class<?> cl = getProxyClass0(loader, intfs);
		final Constructor<?> cons = cl.getConstructor(constructorParams);
		//调用有参的构造方法 传入invocatinghandler
		return cons.newInstance(new Object[]{h});
    }

	private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }
        
        return proxyClassCache.get(loader, interfaces);
    }
	
}
  1. 内存中生成的代理类
public final class $Proxy0 extends Proxy
  implements Person
{
  private static Method m1;
  private static Method m3;
  private static Method m2;
  private static Method m0;

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

  public final boolean equals(Object paramObject)
    throws 
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void listen()
    throws 
  {
    try
    {
      this.h.invoke(this, m3, null);
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final String toString()
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final int hashCode()
    throws 
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m3 = Class.forName("com.wh.Person").getMethod("listen", new Class[0]);
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}
cglib动态代理
spring代理模式的使用和切换

默认当bean实现接口时使用jdk动态代理,没有实现时使用cglib
spring利用动态代理实现aop最主要的两个类:

  1. JdkDynamicAopProxy
  2. CglibAopProxy
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值