1.簡單代理:代理類與真實類組合在一起,代理類與組合類具有相同的方法名
package 動態代理;
/*abstract class*/ interface Interface{
void doSomething();
void somethingElse(String arg);
int a=6;
}
class RealObject implements Interface{
@Override
public void doSomething() {
System.out.println("doSomething");
}
@Override
public void somethingElse(String arg) {
System.out.println("somethingElse "+ arg);
}
}
//使用簡單代理
class SimpleProxy implements Interface{
private Interface proxied;
public SimpleProxy(Interface proxied){
this.proxied = proxied;
}
@Override
public void doSomething() {
System.out.println("SimpleProxy doSomething");
proxied.doSomething();
}
@Override
public void somethingElse(String arg) {
System.out.println("SimpleProxy SomethingElse");
proxied.somethingElse(arg);
}
}
public class SimpleProxyDemo {
public static void main(String[] args) {
//真正對象
Interface iface1 = new RealObject();
iface1.doSomething();
iface1.somethingElse("realObject");
System.out.println("============================");
//簡單代理
SimpleProxy sp = new SimpleProxy(new RealObject());
sp.doSomething();
sp.somethingElse("realObject");
}
}
2.動態代理,主要是invoke方法,關鍵代碼:
先解釋下method.invoke()方法,主要是使用sun.reflect.MethodAccessor的invoke方法:
java.lang.reflect.Method
@CallerSensitive
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
先檢查AccessibleObject的override屬性是否爲true,默認爲false,AccessibleObject是
Method,Field,Constructor的父類,可調用setAccessible方法改變,如果設置爲true,
則表示可以忽略訪問權限的限制,直接調用
如果不是true,則要進行訪問權限檢測,用Reflection的quickCheckMemberAccess方法先檢查是不是public的,
如果不是再用Reflection.getCallerClass()方法獲得到調用這個方法的Class,然後做是否有權限訪問的校驗,
校驗之後緩存一次,以便下次如果還是這個類來調用就不用去做校驗了,直接用上次的結果。
然後就是調用MethodAccessor的invoke方法了,每個Method對象包含一個root對象,
root對象裏持有一個MethodAccessor對象。這個對象由ReflectionFactory方法生成,ReflectionFactory對象在Method類中
是static final的由native方法實例化
//java.lang.reflect.AccessibleObject
void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
throws IllegalAccessException
{
if (caller == clazz) { // quick check
return; // ACCESS IS OK
}
Object cache = securityCheckCache; // read volatile
Class<?> targetClass = clazz;
if (obj != null
&& Modifier.isProtected(modifiers)
&& ((targetClass = obj.getClass()) != clazz)) {
// Must match a 2-list of { caller, targetClass }.
if (cache instanceof Class[]) {
Class<?>[] cache2 = (Class<?>[]) cache;
if (cache2[1] == targetClass &&
cache2[0] == caller) {
return; // ACCESS IS OK
}
// (Test cache[1] first since range check for [1]
// subsumes range check for [0].)
}
} else if (cache == caller) {
// Non-protected case (or obj.class == this.clazz).
return; // ACCESS IS OK
}
// If no return, fall through to the slow path.
slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
}
//java.lang.Method
private MethodAccessor acquireMethodAccessor() {
// First check to see if one has been created yet, and take it
// if so
MethodAccessor tmp = null;
if (root != null) tmp = root.getMethodAccessor();
if (tmp != null) {
methodAccessor = tmp;
} else {
// Otherwise fabricate one and propagate it up to the root
tmp = reflectionFactory.newMethodAccessor(this);
setMethodAccessor(tmp);
}
return tmp;
}
// reflectionFactory在父類AccessibleObject中定義,代碼片段如下:
static final ReflectionFactory reflectionFactory =
AccessController.doPrivileged(
new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
ReflectionFactory生成MethodAccessor:如果noInflation的屬性爲true則直接返回MethodAccessorGenerator創建的一個MethodAccessor,
否則返回DelegatingMethodAccessorImpl,並將他與一個NativeMethodAccessorImpl互相引用。
但DelegatingMethodAccessorImpl執行invoke方法的時候又委託給NativeMethodAccessorImpl了。代碼片段如下:
public MethodAccessor newMethodAccessor(Method paramMethod) {
checkInitted();
if (noInflation) {
return new MethodAccessorGenerator().generateMethod(paramMethod.getDeclaringClass(), paramMethod.getName(), paramMethod.getParameterTypes(), paramMethod.getReturnType(), paramMethod.getExceptionTypes(), paramMethod.getModifiers());
}
NativeMethodAccessorImpl localNativeMethodAccessorImpl = new NativeMethodAccessorImpl(paramMethod);
DelegatingMethodAccessorImpl localDelegatingMethodAccessorImpl = new DelegatingMethodAccessorImpl(localNativeMethodAccessorImpl);
localNativeMethodAccessorImpl.setParent(localDelegatingMethodAccessorImpl);
return localDelegatingMethodAccessorImpl;
}
MethodAccessor實現有兩個版本,一個是Java實現的,另一個是native code實現的。
Java實現的版本在初始化時需要較多時間,但長久來說性能較好;native版本正好相反,啓動時相對較快,
但運行時間長了之後速度就比不過Java版了。這是HotSpot的優化方式帶來的性能特性,
同時也是許多虛擬機的共同點:跨越native邊界會對優化有阻礙作用,它就像個黑箱一樣讓虛擬機難以分析
也將其內聯,於是運行時間長了之後反而是託管版本的代碼更快些。 爲了權衡兩個版本的性能,
Sun的JDK使用了“inflation”的技巧:讓Java方法在被反射調用時,開頭若干次使用native版,
等反射調用次數超過閾值時則生成一個專用的MethodAccessor實現類,生成其中的invoke()方法的字節碼,
以後對該Java方法的反射調用就會使用Java版。
//詳細可參考https://blog.csdn.net/yaerfeng/article/details/52836154
package 模擬動態代理JDK版;
public interface TestInterface {
void boring1();
void boring2();
void interesting(String arg);
void boring3();
}
package 模擬動態代理JDK版;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
class RealAndProxy implements TestInterface{
@Override
public void boring1() {
System.out.println("真實類的 boring1");
}
@Override
public void boring2() {
System.out.println("真實類的 boring2");
}
@Override
public void interesting(String arg) {
System.out.println("真實類的 interesting "+arg);
}
@Override
public void boring3() {
System.out.println("真實類的 boring3");
}
}
class ProxyClass implements InvocationHandler{
private Object proxied;
public ProxyClass(Object proxied){
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理類插入自己的邏輯前");
Object ret = method.invoke(proxied, args);
System.out.println("代理類插入自己的邏輯後");
return ret;
}
}
package 模擬動態代理JDK版;
import java.lang.reflect.Proxy;
public class TestMain {
public static void main(String[] args) {
//第二個參數一定傳的是一個接口
TestInterface proxy = (TestInterface)Proxy.newProxyInstance(TestInterface.class.getClassLoader(),
new Class[]{TestInterface.class}, new ProxyClass(new RealAndProxy()));
proxy.boring1();
proxy.boring2();
proxy.interesting("bonobo");
proxy.boring3();
}
}
首先從Proxy.newProxyInstance(...)進行分析,查看它的源代碼:
@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);
}
/*
* Look up or generate the designated proxy class.
* 查詢或者生成指定的代理類,之前生成的代理類可能被緩存了,這裏只是生成了代理類Class對象
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//根據class對象拿到代理類構造方法
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);
}
}
該方法返回一個特定接口的代理類的實例,代理對象可以分發method調用到專門的調用處理器,然後查看getProxyClass0()方法
/**
* Generate a proxy class. Must call the checkProxyAccess method
* to perform permission checks before calling this.
*/
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表示如果緩存中存在代理類,直接Cache取出,否則生成緩存
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) {
if (supplier != null) {
// supplier might be a Factory or a CacheValue<V> instance
V value = supplier.get();
if (value != null) {
return value;
}
}
// else no supplier in cache
// or a supplier that returned null (could be a cleared CacheValue
// or a Factory that wasn't successful in installing the CacheValue)
// lazily construct a Factory
if (factory == null) {
factory = new Factory(key, parameter, subKey, valuesMap);
}
if (supplier == null) {
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
// successfully installed Factory
supplier = factory;
}
// else retry with winning supplier
} else {
if (valuesMap.replace(subKey, supplier, factory)) {
// successfully replaced
// cleared CacheEntry / unsuccessful Factory
// with our Factory
supplier = factory;
} else {
// retry with current supplier
supplier = valuesMap.get(subKey);
}
}
}
}
以上方法在java.lang.reflect.WeakCache實現,而proxyClassCache
只是Proxy
類的一個WeakCache
類組合對象, 在Proxy
類是這樣定義的:
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
觀察WeakCache
構造參數, 裏面傳入了兩個工廠實例, 兩個工廠均實現了BiFunction
函數接口, KeyFactory
用來生產 緩存 key
,ProxyClassFactory
用來生產字節碼 。
https://blog.csdn.net/lsgqjh/article/details/68486433 參考
查看生成的代理類對象
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import 模擬動態代理JDK版.TestInterface;
public final class $Proxy0
extends Proxy
implements TestInterface
{
private static Method m1;
private static Method m4;
private static Method m3;
private static Method m5;
private static Method m2;
private static Method m6;
private static Method m0;
public $Proxy0(InvocationHandler paramInvocationHandler)
{
super(paramInvocationHandler);
}
public final boolean equals(Object paramObject)
{
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 boring1()
{
try
{
this.h.invoke(this, m4, null);
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void boring3()
{
try
{
this.h.invoke(this, m3, null);
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void boring2()
{
try
{
this.h.invoke(this, m5, null);
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final String toString()
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void interesting(String paramString)
{
try
{
this.h.invoke(this, m6, new Object[] { paramString });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final int hashCode()
{
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") });
m4 = Class.forName("模擬動態代理JDK版.TestInterface").getMethod("boring1", new Class[0]);
m3 = Class.forName("模擬動態代理JDK版.TestInterface").getMethod("boring3", new Class[0]);
m5 = Class.forName("模擬動態代理JDK版.TestInterface").getMethod("boring2", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m6 = Class.forName("模擬動態代理JDK版.TestInterface").getMethod("interesting", new Class[] { Class.forName("java.lang.String") });
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());
}
}
}
總結:JDK的動態代理會創建一個新的代理類對象,該代理類對象中組合了實現InvocationHandler舊的代理類的對象,新的代理類調用boring系列方法和interesting方法時,實際上轉化爲舊的代理類對象調用invoke方法,invoke方法裏的參數是真實對象
以上反編譯代碼通過Java Compiler工具生成
關於Cglib第三方代理轉到下一篇