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第三方代理转到下一篇