1.接口类
public interface UserService {JSONObject getUser();}
接口实现类
public class UserServiceImpl implements UserService {@Overridepublic JSONObject getUser() {JSONObject object = new JSONObject();object.put("name", "meikb");return object;}}
3.1代理类
使用代理类来 传递要代理的对象,这个对象可以是任何对象,所有可以是obj, 也可传入类.
3.1.1 object
public class ProxyHandler implements InvocationHandler {private Object object; //定义obj对象可以支持任何对象传入public ProxyHandler(Object object){this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(method.getName() + "方法被调用");Object result = method.invoke(object, args);System.out.println(method.getName() + "调用完成");return result;}public Object getJDKProxy(Object object){return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);}}
3.1.2 class
public class ProxyHandler implements InvocationHandler {private Class clazz; //传入class参数@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(method.getName() + "方法被调用");Object result = method.invoke(clazz.newInstance(), args);System.out.println( "结果" + result.toString());System.out.println(method.getName() + "调用完成");return result;}public <T>T getJDKProxy(Class clazz){this.clazz = clazz;return (T)Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);}}
4.使用方式
1.对象传入调用方式
public class ProxyMain {public static void main(String[] args) {UserService userService = new UserServiceImpl();ProxyHandler handler = new ProxyHandler(userService);UserService userProxy = (UserService)handler.getJDKProxy(userService);System.out.println(userProxy.getUser().toJSONString());}}
2.class传入调用方式
public class UserMain {public static void main(String[] args) {ProxyHandler handler = new ProxyHandler();UserService userService = handler.getJDKProxy(UserServiceImpl.class);userService.getUser();}}
5.实现原理

1.当调用Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this); 这行代码的是 进入
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);}/** Look up or generate the designated proxy class.*/Class<?> cl = getProxyClass0(loader, intfs);/** Invoke its constructor with the designated invocation handler.*/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<Void>() {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);}}
里面有一个方法是 getProxyClass0 就是获取代理类,获取代理类通过发射就可以获取代理对象。getProxyClass0 内部
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 ProxyClassFactoryreturn proxyClassCache.get(loader, interfaces);}
直接调用proxyClassCache.get 可以看到生成代理类的时候 是存在缓存的 ,提高效率
public V get(K key, P parameter) {Objects.requireNonNull(parameter);expungeStaleEntries();Object cacheKey = CacheKey.valueOf(key, refQueue);// lazily install the 2nd level valuesMap for the particular cacheKeyConcurrentMap<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 valuesMapObject subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));Supplier<V> supplier = valuesMap.get(subKey);Factory factory = null;while (true) {......}}
上面是通过 subKeyFactory.apply(key, parameter) 这个在返回到Proxy 内部调用内部类
public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);final byte[] var4 = var3.generateClassFile();if (saveGeneratedFiles) {......}return var4;}private byte[] generateClassFile() {this.addProxyMethod(hashCodeMethod, Object.class);this.addProxyMethod(equalsMethod, Object.class);this.addProxyMethod(toStringMethod, Object.class);Class[] var1 = this.interfaces;int var2 = var1.length;int var3;Class var4;for(var3 = 0; var3 < var2; ++var3) {var4 = var1[var3];Method[] var5 = var4.getMethods();int var6 = var5.length;for(int var7 = 0; var7 < var6; ++var7) {Method var8 = var5[var7];this.addProxyMethod(var8, var4);}}......}
可以看到是通过io 把新生成的代码写到文件中,然后通过反编译生成class文件。
