proxy 簡化版本

public interface People {
    public String eat(String param);
}

public class Jack implements People {
    @Override
    public String eat(String param) {
        System.out.println("=========Jack老師喜歡吃東=======");
        return "=========Jack老師喜歡吃東=======";
    }
}

public class Advice implements InvocationHandler1 {
    
    People people;//接口,傳進來實例
    
    public Advice(People people) {
        this.people = people;
    }
    
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //前置加強
        before();
        //被代理方
        Object value = method.invoke(people,args);
        //後置加強
        after();
        return value;
    }

    private void before() {
        System.out.println("===========jack吃飯以前�?要洗�?==========");
    }

    private void after() {
        System.out.println("===========jack吃完飯要洗碗=============");
    }
}

public class MyTest {
    public static void main(String[] args) {
        People proxyObject = (People) Proxy1.newProxyInstance(MyTest.class.getClassLoader(),
                new Class<?>[] { People.class }, new Advice(new Jack())); // 獲取代理,MyTest.class.getClassLoader()是類加載器,
        //new Advice是對實現類new Jack()的加強,People.class是接口,在吃飯以前以後要洗手,

        proxyObject.eat("chi");// proxyObject是在內存的代理對象,對象名字$Proxy數字,
  
        //proxyObject = com.zhuguang.jack.aop.jdkProxy.Jack@5e5792a0,裏面的h = com.zhuguang.jack.aop.jdkProxy.Advice@26653222

     // $Proxy0/1 extends Proxy1 implements People,Proxy裏面有一個屬性InvocationHandler h; // proxyObject.eat("chi")調用的是h.invoke(Object proxy, Method method, Object[] // args), // h.invoke()方法調到advice.invoke(), } }

 

public class Proxy1 implements java.io.Serializable {

    private static final long serialVersionUID = -2222568056686623797L;
    private static final Class<?>[] constructorParams = { InvocationHandler1.class };
    private static final WeakCache1<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache1<>( new ProxyClassFactory());
    protected InvocationHandler1 h;
    private Proxy1() {}

    protected Proxy1(InvocationHandler1 h) {
        Objects.requireNonNull(h);
        this.h = h;
    }

    //一個利用給定的類加載器和接口類數組生成,定義並返回代理類對象的工廠方法。代理類生成工廠。
    private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> {
        private static final String proxyClassNamePrefix = "$Proxy1";
        private static final AtomicLong nextUniqueNumber = new AtomicLong();
        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
            String proxyPkg = null; // 代理類的包名
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;//生成代理類的訪問標誌, 默認是public final的
            //驗證全部非公共代理接口都在同一個包中
            for (Class<?> intf : interfaces) {
                int flags = intf.getModifiers();//獲取接口的訪問標誌
                //若是接口的訪問標誌不是public, 那麼生成代理類的包名和接口包名相同
                if (!Modifier.isPublic(flags)) {
                    accessFlags = Modifier.FINAL;//生成的代理類的訪問標誌設置爲final
                    String name = intf.getName();//獲取接口全限定名, 例如:java.util.Collection
                    int n = name.lastIndexOf('.');
                    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));//剪裁後獲得包名:java.util
                    if (proxyPkg == null) {//生成的代理類的包名和接口包名是同樣的
                        proxyPkg = pkg;
                    } else if (!pkg.equals(proxyPkg)) {//代理類若是實現不一樣包的接口, 而且接口都不是public的, 那麼就會在這裏報錯
                        throw new IllegalArgumentException("non-public interfaces from different packages");
                    }
                }
            }
            //若是接口訪問標誌都是public的話, 那生成的代理類都放到默認的包下:com.sun.proxy
            if (proxyPkg == null) {
                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
            }
            long num = nextUniqueNumber.getAndIncrement();
            String proxyName = proxyPkg + proxyClassNamePrefix + num;
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);//com.sun.proxy.$Proxy10,[interface proxy.People],
            try {// 返回代理類對象,根據二進制文件生成相應的Class實例。
                return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
            } catch (Exception  e) {
                System.out.println(e.toString());
            }
            return null;
        }
    }

    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler1 h) throws IllegalArgumentException {
        final Class<?>[] intfs = interfaces.clone();//[interface proxy.People], 
        Class<?> cl =  proxyClassCache.get(loader, intfs);//先走WeakCache的get(),再經過Factory的get方法,最後經過ProxyClassFactory的apply()獲取代理類的Class對象。
        try {
            // 從代理類對象中查找參數爲InvocationHandler的構造器,獲取參數類型是InvocationHandler.class的代理類構造器
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler1 ih = h;
            // 檢測構造器是不是Public修飾,若是不是則強行轉換爲能夠訪問的。
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            // 經過反射,將h做爲參數,實例化代理類,返回代理類實例。2.利用反射技術實例化代理類,並返回實例化對象。傳入InvocationHandler實例去
            //構造一個代理類的實例,全部代理類都繼承自Proxy, 所以這裏會調用Proxy的構造器將InvocationHandler引用傳入,
            return cons.newInstance(new Object[] { h });
        } catch (Exception e) {
            throw new InternalError(e.toString(), e);
        } 
    }

    private static native Class<?> defineClass0(ClassLoader loader, String name, byte[] b, int off, int len);
}
final class WeakCache1<K, P, V> {
    private final BiFunction<K, P, V> valueFactory;

    public WeakCache1(BiFunction<K, P, V> valueFactory) {//構造方法,,,
        this.valueFactory = Objects.requireNonNull(valueFactory);//new ProxyClassFactory()
    }

    public V get(K key, P parameter) { 
        Supplier<V> supplier = null; 
        Factory factory = null;

        while (true) {
            if (supplier != null) {
                V value = supplier.get(); if (value != null) {
                    return value; 
                }
            }
            if (factory == null) {
                factory = new Factory(key, parameter );
            }
            if (supplier == null) {
                if (supplier == null) {
                    supplier = factory;
                }
            } 
        }
    }

    private final class Factory implements Supplier<V> {
        private final K key;
        private final P parameter;

        Factory(K key, P parameter) {
            this.key = key;
            this.parameter = parameter;
        }

        @Override
        public synchronized V get() {  
            V value = null;
            // valueFactory就是WeakCache的valueFactory屬性,由於Factory是WeakCache的內部類,因此能夠直接訪問WeakCache的valueFactory屬性
            value = valueFactory.apply(key, parameter);
            return value;
        }
    }

}
相關文章
相關標籤/搜索