1.接口类
public interface UserService {
JSONObject getUser();
}
接口实现类
public class UserServiceImpl implements UserService {
@Override
public 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;
}
@Override
public 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参数
@Override
public 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 ProxyClassFactory
return 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 cacheKey
ConcurrentMap<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 valuesMap
Object 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文件。