设计模式-代理模式-java动态代理

在框架开发中动态代理模式使用较为普遍,与此同时JDK为我们提供了好用的接口,
1.InvocationHandler(代理接口,代理类需要实现它)
2.Proxy(代理类,用来实现代理操作)

实例

项目结构

设计模式-代理模式-java动态代理_第1张图片

Proxy(自定义的代理接口类,并非jdk自带的)

public interface Proxy {
    void show(User user);
}

POJO 类 User

@AllArgsConstructor
@ToString
public class User {
    private String name;
    private Integer age;
}

ProxyUser(代理类)

@AllArgsConstructor
public class ProxyUser implements InvocationHandler {
    private Proxy proxy;

    public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
        System.out.println("ProxyUser :: invoke() ----------进入-----------");
        method.invoke(proxy,args);
        System.out.println("ProxyUser :: invoke() ----------退出-----------");
        return null;
    }
}

TargetUser (实际目标类)

public class TargetUser implements Proxy {

    public void show(User user){
        System.out.println("TargetUser :: show(): "+user.toString());
    }

}

测试类 Test

public class Test {
    public static void main(String[] args) {
        TargetUser targetUser=new TargetUser();
        InvocationHandler invocationHandler=new ProxyUser(targetUser);
        com.ecit.lyy.proxy.dynamic_proxy.Proxy proxy=(com.ecit.lyy.proxy.dynamic_proxy.Proxy)Proxy.newProxyInstance(
                invocationHandler.getClass().getClassLoader(),
                targetUser.getClass().getInterfaces(),
                invocationHandler);
        proxy.show(new User("show.tom",15));


    }
}

结果如下

ProxyUser :: invoke() ----------进入-----------
TargetUser :: show(): User(name=show.tom, age=15)
ProxyUser :: invoke() ----------退出-----------

注意点

1.代理类实现的是jdk中的InvocationHandler接口,而非我们自定义的接口。

2.目标类实现的是自定义的Proxy接口,而非JDK自带的Proxy。

3.代理类通过实现InvocationHandler的invoke方法,来处理实际业务逻辑,我们可以在method.invoke()前后加入我们自己的逻辑。

4.使用Proxy.newProxyInstance来实现代理,它有三个参数

源码(它们的使用方式在源码里都有)

InvocationHandler (接口)

package java.lang.reflect;


public interface InvocationHandler {

   
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

Proxy(jdk)

package java.lang.reflect;
import (省略。。)

/**
 *     InvocationHandler handler = new MyInvocationHandler(...);
 *     Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
 *     Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
 *                     newInstance(handler);
 * 或者:
 *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
 *                                          new Class[] { Foo.class },
 *                                          handler);
 */
public class Proxy implements java.io.Serializable {

    private static final long serialVersionUID = -2222568056686623797L;

    private static final Class[] constructorParams =
        { InvocationHandler.class };
	......
    protected InvocationHandler h;
    private Proxy() {
    }
    protected Proxy(InvocationHandler h) {
        Objects.requireNonNull(h);
        this.h = h;
    }
    

	......
    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);//为非空对象

        final Class[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

    
        Class cl = getProxyClass0(loader, intfs);//获取代理类

        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

            final Constructor cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            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);
        }
    }

   ......
   
    public static boolean isProxyClass(Class cl) {
        return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
    }

 
    @CallerSensitive
    public static InvocationHandler getInvocationHandler(Object proxy)
        throws IllegalArgumentException
    {
        /*
         * Verify that the object is actually a proxy instance.
         */
        if (!isProxyClass(proxy.getClass())) {
            throw new IllegalArgumentException("not a proxy instance");
        }

        final Proxy p = (Proxy) proxy;
        final InvocationHandler ih = p.h;
        if (System.getSecurityManager() != null) {
            Class ihClass = ih.getClass();
            Class caller = Reflection.getCallerClass();
            if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
                                                    ihClass.getClassLoader()))
            {
                ReflectUtil.checkPackageAccess(ihClass);
            }
        }

        return ih;
    }

    private static native Class defineClass0(ClassLoader loader, String name,
                                                byte[] b, int off, int len);
}

你可能感兴趣的:(设计模式)