jdk动态代理
helloWorld
好了,在介绍完这两个接口(类)以后,我们来通过一个实例来看看我们的动态代理模式是什么样的:
思路:
我们helloworld中有两个接口,一个接口是自定义的,另一个是创建动态代理类所需要实现的InvocationHandler接口。
有两个对象:真实对象(实现自定义接口)、代理对象(实现InvocationHandler接口)、代理对象
首先我们定义了一个Subject类型的接口,为其声明了两个方法:
接口
//自定义接口
public interface UserService {
String hello();//测试无参
public String getUserByName(String name); //测试有参
}
真实对象
接着,定义了一个类来实现这个接口,这个类就是我们的真实对象,RealSubject类:
//真实对象(被代理对象)
public class UserServiceImpl implements UserService {
@Override
public String hello() {
return "hello";
}
@Override
public String getUserByName(String name) {
System.out.println("从数据库中查询到:" + name);
return name;
}
}
下一步,我们就要定义一个动态代理类了,前面说个,每一个动态代理类都必须要实现 InvocationHandler
这个接口,因此我们这个动态代理类也不例外:
InvocationHandler
写明我们的代理逻辑:实现InvocationHandler接口,在invoke方法中编写代理逻辑,这个实现类作为handler
我们来看看InvocationHandler这个接口的唯一一个方法 invoke 方法:
interface InvocationHandler{
Object invoke(Object proxy, // 代理对象
Method method,
Object[] args) throws Throwable;
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyHandler implements InvocationHandler {
// 目标类对象
private Object target;
// 构造器传入目标类对象
public MyHandler(Object target) {
this.target = target;
}
// 创建JDK代理 // 为什么要放在handler里创建代理对象:spring也是这么做的,工厂同时也是handler
public Object createJDKProxy() {
Class clazz = target.getClass();
// 创建JDK代理需要3个参数,目标类加载器、目标类接口、代理类对象(即本身)
return Proxy.newProxyInstance(
clazz.getClassLoader(), // 传入加载器
clazz.getInterfaces(), // 传入接口
this); // 传入handler对象 // 代理的逻辑
// 创建了代理对象
}
@Override
public Object invoke(Object proxy,
Method method,
Object[] args) throws Throwable {
// 在代理真实对象前我们可以添加一些自己的操作
System.out.println("前置通知");
Object result = method.invoke(target, args);//通过反射调用传入真实对象subject的方法method,method方法的参数是args
// 在代理真实对象后我们也可以添加一些自己的操作
System.out.println("后置通知");
return result;
}
}
handler一般都要实现如下内容
- 构造函数:将目标对象传入
- 重写invoke():写AOP增强的所有逻辑
- 重写getProxy():这个方法并不是我们InvocationHandler接口的方法,但是写在handler实现类中后handler就能产生代理对象了,也就是说handler同时是代理工厂+handler
当然我们上面的处理逻辑要用到的时候利用lambda表达式直接new也行
创建代理实例
import sun.misc.ProxyGenerator;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
// System.getProperties().put("com.proxy.ProxyGenerator.saveGeneratedFiles","true");
UserService userService = new UserServiceImpl();
MyHandler myHandler = new MyHandler(userService);// 会调用接口的实现类对象
// 获取代理对象
UserService proxy = (UserService) myHandler.createJDKProxy();
// 输出看看代理对象的类型
System.out.println(proxy.getClass());// com.sun.proxy.$Proxy0
}
}
生成的代理类
JDK动态代理的原理还是反射,如
package com.sun.proxy;
import JDK.UserService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
// 继承了Proxy,里面的方法是调用的super.h.invoke()。
public final class $Proxy0 extends Proxy implements UserService {
// 父类为Proxy、UserService
private static Method m1;
private static Method m3;
private static Method m4;
private static Method m2;
private static Method m0;
// 将handler对象传给父类Proxy,父类中有成员属性InvocationHandler
public $Proxy0(InvocationHandler var1) throws { // 构造器传入InvocationHandler
super(var1);//调用父方法的有参构造 // 赋给父类的属性h即 this.h = h;获取时是super.h
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String hello() throws {
try {
// 即调用handler对象的invoke方法, 这里的内容其实基本是我们写过的
return (String)super.h.invoke(this, //代理对象,我们终于知道MyHandler.invoke()的第一个参数是什么了
m3, // m3为hello()的method对象
(Object[])null);// // hello()的method的参数
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String getUserByName(String var1) throws {
try {
return (String)super.h.invoke(this, // 代理对象
m4,// m4 为getUserByName()的method对象
new Object[]{var1}); // 1个参数
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
// 拿到method对象
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
// 无参hello()
m3 = Class.forName("JDK.UserService").getMethod("hello");
// 有参getUserByName(String)
m4 = Class.forName("JDK.UserService").getMethod("getUserByName", Class.forName("java.lang.String"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
helloworld进阶:https://blog.csdn.net/qq_27717967/article/details/73561179
将内存中的动态代理对象生成class文件
代理class的生成路径是在idea的工作空间下的 com\sun\proxy 目录中,如下图所示
//保存生成的对象
public static void generateClassFile(Class clazz, String ProxyName){//$Proxy0
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName,
clazz.class.getInterfaces() );//生成了字节数组(字节码)
//String path = clazz.getResource("").getPath();
String path="C:/";
paths.sout;
FileOutputStream out=null;
try{
out = new FileOutputStream(path+ProxyName+".class");
out.write(proxyClassFile);
out.flush();
}finally{
out.close();
}
}
cglib生成class文件:
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "e:\\class");
jdk动态代理源码解读
一Proxy.newProxyInstance()
- getProxyClass0(loader类加载器, intfs接口列表)获得代理类
- cl.getConstructor(constructorParams构造器形参列表);反射得到代理类构造器
- cons.newInstance(new Object[]{h}); 反射创建代理实例对象
@CallerSensitive // Proxy
public static Object Proxy.newProxyInstance(
ClassLoader loader, //一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
Class<?>[] interfaces, //一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
InvocationHandler h)//一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上 // 重写了invoke方法
throws IllegalArgumentException {
//检验handler不为空,为空的话没有代理逻辑,所以得报错
Objects.requireNonNull(h);
// 拷贝一份接口类
final Class<?>[] intfs = interfaces.clone();
//获得安全管理器,进行一些安全性检查
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
//-----------重要----------------------
// 从缓存中拿到代理class对象,当然可能拿不到,就创建//生成代理类字节码以及加载都在这里进行
// 一组接口只能生成一个代理类,因为从缓存中拿是以类加载器和接口来取的,如果想要同组接口不同的代理类,得变类加载器
Class<?> cl = getProxyClass0(loader, intfs);//生成字节码,生成class对象//接口复数
//从上步出来已经有代理类了,接下来没有那么重要,还是上句最重要,所以我们得点进去看
//------------------------------
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
// --------重要-------------
//从生成的代理类中获取构造函数,具体哪个构造函数可以通过constructorParams指定,是个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;
}
});
}
// 生成代理对象,传入构造参数,将InvocationHandler作为参数,实例化代理对象
return cons.newInstance(new Object[]{h});// 参数为InvocationHandler对象
} 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);
}
}
二、Proxy.getProxyClass0()
1、Proxy.getProxyClass0()
获取符合loader+intfs的代理类Class对象,参数为类加载器和接口类。
没有就创建
- proxyClassCache代理类缓存.get(loader类加载器, interfaces接口列表);
// Proxy.java
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
//接口的数量是否大于65535,报错
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");11
}
// 如果缓存类中已经存在实现了对应接口的代理类,那么直接返回缓存副本即可,
// 否则将通过代理工厂ProxyClassFactory创建代理类
return proxyClassCache.get(loader, interfaces);
// 说一下在这里invocationHandler去哪了:生成代理类的时候逻辑是按照接口来的,跟h没有关系,直到生成具体的代理实例时才传入h生成具体的代理对象
// 生成的代理类的构造函数的参数就是ih
}
2、proxyClassCache
上面最重要的是代理类缓存WeakCache,他是什么呢?
proxyClassCache
是Proxy.java
中的一个静态属性,在JVM加载类的时候就加载好了
- proxyClassCache用于通过类加载和接口获得生成的代理类class
<ClassLoader, Class<?>[], Class<?>>
的意思是通过类加载器+接口数组,得到一个代理类
// proxyClassCache静态属性 //Proxy.java
// 新建了一个WeakCache类型的对象,该类型构造方式为传入key工厂和代理类工厂
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache
= new WeakCache<>(new KeyFactory(), //作为subKeyFactory,产生二级map的副key
new ProxyClassFactory()); //作为valueFactory,生成代理类
2.1 WeakCache类基础介绍
proxyClassCache的类型是WeakCache
2.0) WeakCache的构造函数:
-
BiFunction介绍:https://www.jianshu.com/p/8dc46a2dc21d
-
WeakCache要起到的一个效果是用主副键得到一个值:
{(key,sub-key)-->value}
-
WeakCache<K,P,V>中,K代表key值,P代表参数,V代表存储的值。 此类用于缓存{(key,sub-key)-->value}键值对。 具体实现是一个ConcurrentMap<Object,ConcurrentMap<Object,Supplier<V>>> (Supplier是一个接口,就一个get方法用于获得值,不过是V的包裹类), 第一个Object就是key(这里表达式不用K是因为key值可以为null), 第二个Object就是sub-key。
根据 ,我们知道WeakCache的构造函数传入了两个BiFunction函数。BiFunction函数是代表传入两个参数,返回一个返回值的函数,类似于我们原来的函数式接口
而在WeakCache实例化的时候,传入了两个BiFunction函数(他同时也是一个类),分别是subKeyFactory
和valueFactory
,首先明确他们是两个函数。其次这两个参数实参分别是subKeyFactory=new KeyFactory()
,
valueFactory=new ProxyClassFactory()
那么就知道了KeyFactory和ProxyClassFactory肯定实现了BiFunction这个类
而事实上在Proxy的内部类中KeyFactory确实证实了我们的猜想。但我们往下看的话会很晕,我们得先记住:
Object KeyFactory.apply(classLoader,Class<?>[] interfaces)
体会一下它的参数和返回值Class<?> ProxyClassFactory.apply(ClassLoader,Class<?>[] interfaces)
拿到最终的代理类
//K代表key的类型,P代表参数的类型,V代表value的类型。
// WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache 说明proxyClassCache存的值是Class<?>对象,正是我们需要的代理类对象。
final class WeakCache<K, P, V> {
private final ReferenceQueue<K> refQueue
= new ReferenceQueue<>();
// 两个map
// the key type is Object for supporting null key
private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
= new ConcurrentHashMap<>();
private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
= new ConcurrentHashMap<>();
// 两个工厂 // K为类加载器,P为接口数组,V为代理类Class<?>
private final BiFunction<K, P, ?> subKeyFactory; // 生成subKey
private final BiFunction<K, P, V> valueFactory; //ProxyClassFactory // 生成代理类
// 构造函数
public WeakCache(BiFunction<K, P, ?> subKeyFactory,
BiFunction<K, P, V> valueFactory) {
this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
this.valueFactory = Objects.requireNonNull(valueFactory);
}
WeakCache主要内容
V get(K key, P parameter)
boolean containsValue(V value)
int size()
expungeStaleEntries()
ReferenceQueue<K> refQueue
ConcurrentHashMap<Object, ConcurrentMap<Object, Supplier<V>>> map
:最重要。相当于依赖2个key才能得到一个值,表示为(key, sub-key) -> value
。- key是传进来的Classloader进行包装后的对象,
- sub-key是由WeakCache构造函数传入的
KeyFactory()
生成的。 - value就是产生代理类的对象,是由WeakCache构造函数传入的
ProxyClassFactory()
生成的。
我们再从语言上理解下刚才的这两句:
subKeyFactory=new KeyFactory()
生产key
valueFactory=new ProxyClassFactory()
生产代理类对象
好吧,他们的参数是都是加载器+接口,返回值分别是Object
和Class
。
我们知道了现在WeakCache对象中有了一些功能,你只要传入一个加载器+接口,我们就可以得到一个
再根据前面的(cachekey, sub-key) -> 工厂
ConcurrentMap<Object cachekey,
ConcurrentMap<Object sub-key,
Supplier<V> supply>
> map
两个BiFunction.apply()
1) 一级工厂KeyFactory.apply生成接口弱引用
它又被称为subKeyFactory
- 继承BiFunction,代表输入两个参数,输出一个参数
- KeyFactory的功能就是传入接口,生成接口的若引用(被称为KeyX)
private static final class KeyFactory
implements BiFunction<ClassLoader, Class<?>[], Object>
{
@Override // 返回Object类型 // 即输入两个参数,输出一个参数 //得到的object对象就是个id而已
public Object apply(ClassLoader classLoader, // 参数1
Class<?>[] interfaces) { // 参数2
// 判断接口数量
switch (interfaces.length) {
case 1: return new Key1(interfaces[0]); // 1个接口 // 里面是先算hash值然后创建接口的弱引用
case 2: return new Key2(interfaces[0], interfaces[1]); // 2个接口 // 为每个接口生成弱引用
case 0: return key0; // 没有接口
default: return new KeyX(interfaces); // 多个接口 // 为每个接口生成弱引用
}
}
}
我们可以观察到,根本没用到classLoader
KeyFactory的功能就是传入接口,生成接口的若引用(被称为KeyX);
private static final class KeyX {
private final int hash;
private final WeakReference<Class<?>>[] refs;
// KeyX构造函数,生成接口弱引用后放到数组refs[]中。Key1和Key2也差不多
KeyX(Class<?>[] interfaces) {
hash = Arrays.hashCode(interfaces);
refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
refs[i] = new WeakReference<>(interfaces[i]);
}
}
上面就是对接口生成了弱引用。
弱引用:该引用一旦经历垃圾回收,该不再引用
2) 二级工厂ProxyClassFactory.apply生成代理类
它又被称为valueFactory
- 代理类名称样式案例:
$Proxy3.class
- 前缀:代理类的前缀是
"$Proxy"
- 序号:代理类的序号是通过
AtomicLong
保证的 - 所在包:默认生成的包名是
com.sun.proxy
,如果接口有不是public
,生成在该接口所在包下,如果非public的接口原来不都在同一个包下
,那么将报错
- 访问权限:默认的代理类访问权限是
public final
,如果有接口不是public,那么访问权限变为final
,去掉public - 同样是继承了BiFunction,输入两个参数,输出一个参数
- 两个参数分别是
ClassLoader loader和 Class<?>[] interfaces
,返回值是生成的代理类Class<?>
//代理类生成工厂 // 前面的缓存中第二个参数
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>> {//这里的BiFunction输入是(类加载器+接口数组),返回代理类
//代理类名称前缀
private static final String proxyClassNamePrefix = "$Proxy";
// 生成代理类的序号, 以此来确定唯一的代理类 // 原子long
private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override // apply意思是既是消费者也是生产者
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
// IdentityHashMap如果提交重复的key,那么都会存储,但是他们get方法会返回null
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);//map大小
for (Class<?> intf : interfaces) {
Class<?> interfaceClass = null;
interfaceClass = Class.forName(intf.getName(), false, loader);
//这里遍历interfaces数组进行验证, 主要做三件事情
//1.intf是否可以由指定的类加载进行加载
//2.intf是否是一个接口
//3.intf在数组中是否有重复
// 然后我们发现这个for里只是检验
}
//生成代理类的包名
String proxyPkg = null;
//生成代理类的访问标志, 默认是public 且 final的
int accessFlags = Modifier.PUBLIC | Modifier.FINAL; // 00....011
for (Class<?> intf : interfaces) {
//获取接口的访问标志
int flags = intf.getModifiers();
//如果接口的访问标志不是public, 那么生成代理类的包名和接口包名相同
if (!Modifier.isPublic(flags)) {
//生成的代理类的访问标志设置为final,注意不是public了
accessFlags = Modifier.FINAL;
//获取接口全限定名, 例如:java.util.Collection
String name = intf.getName();
int n = name.lastIndexOf('.');
//剪裁后得到包名:java.util
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
//生成的代理类的包名和接口包名是一样的
if (proxyPkg == null) {// 第一个接口进来时候是null,第二个接口进来就!=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();
//生成代理类的全限定名, 包名+前缀+序号, 例如:com.sun.proxy.$Proxy0
String proxyName = proxyPkg + proxyClassNamePrefix + num;
// ---------核心代码-----------
// 用sun.misc.ProxyGenerator来生成字节码
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, // 生成的类名字
interfaces, // 接口
accessFlags); // 代理类类型final或者public final的
try {
//根据二进制文件生成相应的Class实例 //native
return defineClass0(loader, proxyName,
proxyClassFile,// 二进制
0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
}
3、 proxyClassCache.get()
先说明一下这步是从哪来的,我们前面是介绍了proxyClassCache的组成是个WeakCache,显示它不是动态代理的逻辑了,那么何如通过它得到我们的代理类呢?
答案在于通过构造函数中传入的两个BiFunction来一步步回调得到最终的代理类。换句话说,WeakCache只知道怎么调用两个连接两个BitFunction最终得到一个值,而动态代理只需要提供两个BitFunction即可。而这两个BitFunction我们之前讲过了
跟踪proxyClassCache.get(loader, interfaces);
本段代码我们主要关心V value = supplier.get();
其中supplier本质是factory,通过new Factory(key, parameter, subKey, valuesMap)
创建
cacheKey
= CacheKey.valueOf(key, refQueue); 得到主键,主键从一级map里拿二级map- valuesMap=map.get(
cacheKey
) 一级map里拿到二级map,也就是用类加载器拿到二级map subKey
= subKeyFactory.apply(key类加载器, parameter接口类); 一级工厂,产生二级key,二级key是接口的封装- 副键,依靠它从二级map里得到能生成最终值的生产者
- supplier = valuesMap.get(
subKey
); 二级map V value
= supplier.get();生产者生产值
// 伪代码
public V proxyClassCache.get(K key, //类加载器
P parameter) {// 接口
// cacheKey=key+refQueue
// 主缓存key=类加载器+弱引用队列
Object cacheKey = CacheKey.valueOf(key, refQueue);
// 用缓存key(主key) 从map 拿到二级valuesMap 。
// 这里主要利用的是类加载器
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
// subKey=key+parameter
// 用subKeyFactory的BiFunction传入key+parameter返回Object 即返回subKey(副key),但其实这个key只有接口的信息
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
// 从二级map中取得subkey对应的supplier,supplier即工厂
// 这里主要利用的是接口的弱引用
Supplier<V> supplier = valuesMap.get(subKey);
// 从工厂中拿到代理对象拿到代理对象
V value = supplier.get();
return value;
}
// WeakCache.get()
public V proxyClassCache.get(K key, //类加载器
P parameter) {//接口类
// Object工具类 类加载器为空抛出异常用于验证
Objects.requireNonNull(parameter);
// 将被clear的key值对应值从map中删除
expungeStaleEntries();
//map中的key值和value值都是弱引用,这里valueOf静态方法,返回key的新建弱引用对象,
//这里有一点要注意CacheKey弱引用对象的hash值跟key值绑定,所以虽然新建了弱引用对象
//但是key值一样在map中就能取到对应的值
// 用 类加载器+引用队列(就是接口列表) 组成 缓存key,如果key==null,则cacheKey=new Object();
Object cacheKey = CacheKey.valueOf(key, refQueue);
// 用缓存key从一级map中拿到二级map // 懒汉模式
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
// 下面的整个if其实就是单例模式创建一个map给cachekey对应的二级map而已
// 如果二级map值map为空,就新增
if (valuesMap == null) {
// putIfAbsent:不存在才添加后返回null,如果有就直接返回现有值,不修改
// 按理说我们创建的时候为了同步需要加锁,但是ConcurrentMap本来就是线程安全的了,假设线程1,2同时到达此处,线程1先进去后设置完了返回null,线程2进入后返回线程1传入的值
// 同时注意参数2在传入的同时还赋值给valuesMap了
ConcurrentMap<Object, Supplier<V>> oldValuesMap
= map.putIfAbsent(cacheKey,
valuesMap = new ConcurrentHashMap<>());
// 线程1拿到的是null,跳过下面if //线程2拿到的是线程1的值,按理来说拿到线程1的值不是正好吗,接着往下执行不就行了,但是注意上面线程2new的时候改变valuesMap的值了,所以得改变回去
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}
/* 常见的懒汉模式
if(map==null){
synchronized (map.class){
if(map==null){
map=new Map();
}
}
}
return map;
*/
// 传入key和parameter到subKeyFactory函数中得到subKey
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));//apply生成
// 通过sub-key从valuesMap得到supplier,实质就是factory
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
// // Proxy.newStance第一次执行的时候,supplier,valuesMap都为null。下面从序号①-⑤看
while (true) {
// 从工厂中获得类对象
if (supplier != null) {
// ④从工厂中获得代理类对象
// supplier可以是一个工厂或是一个缓存实例
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)
// ①懒加载工厂
if (factory == null) {
// 创建对应factory,此段代码在死循环中,下一次supplier.get()将会获取到代理类并退出循环
factory = new Factory(key,
parameter,
subKey,
valuesMap);
}
// 懒汉模式给valuesMap中subKey对应的值supplier
if (supplier == null) {
// ②把工厂保存到valuesMap中
// 有则返回旧值不替换,无则传入新值返回null
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
// ③赋值
// factory已经放到valuesMap中了
supplier = factory;
}
// else retry with winning supplier
} else {// 如果原来不为空但是获得不到value,重新弄个新的
// replace的作用的只有在前两个参数组成的键值对匹配的时候才替换
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);
}
}
}
}
从proxyClassCache.get()就能得到代理对象了,那么代理对象一定是在proxyClassCache.get()的某一步生成的。从上面可知是从工厂里获得的,那么就有必要了解一下工厂,即supplier
supplier.get()
// 内部类Factory.java
public synchronized V get() { // serialize access
// re-check
// 再次检查,supplier是否是当前对象
Supplier<V> supplier = valuesMap.get(subKey);
if (supplier != this) {
// something changed while we were waiting:
// might be that we were replaced by a CacheValue
// or were removed because of failure ->
// return null to signal WeakCache.get() to retry
// the loop
return null;
}
// else still us (supplier == this)
// create new value
V value = null;
try {
// 关键
// valueFactory就是WeakCache的valueFactory属性,因为Factory是WeakCache的内部类,所以可以直接访问WeakCache的valueFactory属性,即new ProxyClassFactory(),他是一个BiFunction
// 即传入subkey返回代理对象 //通过类加载器+接口得到一个代理类
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
if (value == null) { // remove us on failure
valuesMap.remove(subKey, this);
}
}
// the only path to reach here is with non-null value
assert value != null;
// wrap value with CacheValue (WeakReference)
CacheValue<V> cacheValue = new CacheValue<>(value);
// put into reverseMap
reverseMap.put(cacheValue, Boolean.TRUE);
// try replacing us with CacheValue (this should always succeed)
if (!valuesMap.replace(subKey, this, cacheValue)) {
throw new AssertionError("Should not reach here");
}
// successfully replaced us with new CacheValue -> return the value
// wrapped by it
return value;
}
调用了valueFactory.apply(key, parameter)
ProxyGenerator.generateProxyClass
创建动态代理class文件
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) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
try {
int var1 = var0.lastIndexOf(46);
Path var2;
if (var1 > 0) {
Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar));
Files.createDirectories(var3);
var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
} else {
var2 = Paths.get(var0 + ".class");
}
Files.write(var2, var4, new OpenOption[0]);
return null;
} catch (IOException var4x) {
throw new InternalError("I/O exception saving generated file: " + var4x);
}
}
});
}
return var4;
}
cglib动态代理
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,cglib的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
CGLIB是一个强大的高性能的代码生成包。被广泛的许多AOP框架使用,如Spring的AOP和dynaop,为他们提供方法的interceptor(拦截),最流行的是OR Mapping工具Hibernate也是使用CGLIB来代理单端的single-ended(多对一和一对一)关联(对集合的延迟抓取是采用其他机制实现)。
-
静态代理和 JDK 代理模式都要求目标对象是实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理-这就是 Cglib 代理
-
Cglib 代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展, 有些书也将Cglib 代理归属到动态代理。
-
Cglib 是一个强大的高性能的代码生成包,它可以在运行期扩展 java 类与实现 java 接口.它广泛的被许多 AOP 的框架使用,例如 Spring AOP,实现方法拦截
-
在 AOP 编程中如何选择代理模式:
\1. 目标对象需要实现接口,用 JDK 代理
\2. 目标对象不需要实现接口,用 Cglib 代理
- Cglib 包的底层是通过使用字节码处理框架 ASM 来转换字节码并生成新的类
在内存中动态构建子类,注意代理的类不能为 final,否则报错
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class EnhancerDemo {
public static void main(String[] args) {
// 1 new Enhancer增强器
Enhancer enhancer = new Enhancer();
// 2 给增强器中传入父类(目标对象类)
enhancer.setSuperclass(EnhancerDemo.class);
// 3 回调方法 // 把实现了MethodInterceptor接口的对象传入增强器,作为回调
enhancer.setCallback(new MethodInterceptImpl()); // this里的intercept方法有代理逻辑
// 4 创建代理对象 可以返回后强制转型
EnhancerDemo demo = (EnhancerDemo) enhancer.create();
demo.test();
System.out.println("-----分割线----下面是System.out.println(demo);的内容---");
System.out.println(demo);
}
public void test() {
System.out.println("目标方法test()被执行");
}
// 内部类,定义在外面也可以
private static class MethodInterceptImpl implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)
throws Throwable {
System.out.println("before方法被执行:" + method);
Object result = methodProxy.invokeSuper(obj, args);
System.out.println("after方法被执行:" + method);
return result;
}
}
}
输出
before方法被执行:public void com.example.demo.EnhancerDemo.test()
目标方法test()被执行
after方法被执行:public void com.example.demo.EnhancerDemo.test()
//-----分割线----下面是System.out.println(demo);的内容---
before方法被执行:public java.lang.String java.lang.Object.toString()
before方法被执行:public native int java.lang.Object.hashCode()
after方法被执行:public native int java.lang.Object.hashCode()
after方法被执行:public java.lang.String java.lang.Object.toString()
com.example.demo.EnhancerDemo$$EnhancerByCGLIB$$c9489e6f@41975e01
思路2
public class ProxyFactory implements MethodInterceptor {
//维护一个目标对象
private Object target;
//构造器,传入一个被代理的对象
public ProxyFactory(Object target) {
this.target = target;
}
//返回一个代理对象: 是 target 对象的代理对象
public Object getProxyInstance() {
//1. 创建一个工具类
Enhancer enhancer = new Enhancer();
//2. 设置父类
enhancer.setSuperclass(target.getClass());
//3. 设置回调函数 MethodInterceptor
enhancer.setCallback(this);
//4. 创建子类对象,即代理对象
return enhancer.create();
}
//重写 intercept 方法,会调用目标对象的方法
@Override
public Object intercept(Object arg0, // 被代理对象
Method method, // 被代理对象的方法
Object[] args, //
MethodProxy arg3) throws Throwable {
System.out.println("Cglib代理模式 ~~ 开始");
Object returnVal = method.invoke(target, args);
System.out.println("Cglib代理模式 ~~ 提交");
return returnVal;
}
}
首先调用了toString(),然后调用hashCode(),
同时可以看到这个类已经改变了,实际上CGLIB代理的类是委托给Cglib2AopProxy类去实现的。
按照前面的示例,我们容易判断出来,Cglib2AopProxy的入口应该是getProxy,也就是说在Cglib2AopProxy类的getProxy()中实现了Enhancer的创建及接口封装。
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// 验证class
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// 创建及配置CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 设置目标列
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
// 设置拦截器
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 生成代理类、创建代理对象
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
工厂
工厂是做什么的?
工厂可以根据传入的handler目标对象的类的信息自动判断是生成cglib的动态代理还是jdk动态代理。
ProxyFactory-helloWorld
前言
本篇将重点剖析ProxyFactory类的源码,很多人不理解为什么要将大部分精力花在讲解ProxyFactory上,毕竟没有人会使用这么底层的Spring AOP实现方式?
ProxyFactory实现代理需要手动设置Traget(目标对象)、Interface(代理接口)、Advice(增强),然后调用getProxy生成代理对象。而使用注解形式的Spring AOP并没有想象中的复杂,不过是寻找所有@Aspect注解的类以及所有@Before等增强,再通过@Pointcut上的匹配条件进行匹配,最后获取到所有匹配的Advice(增强)进行生成代理。因此,注解形式的AOP并不深奥,只不过是帮我们自动寻找匹配增强,并在Spring Ioc创建Bean的过程中寻找合适的时机,调用getProxy生成代理,仅此而已。因此,如果我们将手动硬编码的方式(ProxyFactory)学透了,基本上也就掌握了Spring AOP了,至于注解的形式,我们只需要再探究一下Advice如何获取以及匹配就可以了
剖去注解与Xml的配置,Spring AOP的核心就是ProxyFactory,抓住主线,才能更好的把握源码脉络,不至于被边角的细节所干扰
ProxyFactory代码示例
我们将会写一个UserService接口,定义findUser方法,同时在before跟after使用Advice(增强)对方法进行增强,最后使用ProxyFactory进行代理的生成。
接口:
public interface UserService {
public void findUser();
}
实现类:
public class UserServiceImpl implements UserService {
@Override
public void findUser() {
System.out.println("findUser...");
}
}
2个增强:
// 前置增强
public class LogBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("before log...");
}
}
// 后置增强
public class LogAfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("after log...");
}
}
测试:
public class UserServiceImplImplTest {
@Test
public void findUser() {
// 1. 创建代理工厂
ProxyFactory factory = new ProxyFactory();
// 2. 设置代理目标对象
factory.setTarget(new UserServiceImpl());
// 3. 设置接口 (可以多实现)
factory.setInterfaces(new Class[]{UserService.class});
// 4. 设置增强
factory.addAdvice(new LogBeforeAdvice());
factory.addAdvice(new LogAfterAdvice());
// 5. 获取代理对象
UserService userService = (UserService) factory.getProxy();
userService.findUser();
}
}
运行结果:
before log...
findUser...
after log...
Process finished with exit code 0
ProxyFactory继承关系
下面继承上面
![ProxyFactory](https://i-blog.csdnimg.cn/blog_migrate/f0cf2175fba9a280c543be5897e02f10.png)
我们重点关心一下类,忽略接口
- ProxyConfig:用于保存Proxy的相关基础配置,比如是否使用激进模式optimize、强制开起cglib代理proxyTargetClass、是否暴露代理exposeProxy等,在xml配置中十分常见,例如<aop:aspectj-autoproxy proxy-target-class=“true”/>强制开启Cglib代理
- AdvisedSupport:AOP的配置管理类,比起ProxyConfig,其还保存了targetSource(目标对象的封装)、切面的集合advisors、接口集合interfaces等
- ProxyCreatorSupport:代理工厂的基础类,提供对可配置AopProxyFactory的便捷访问
这样代理工厂中就有了:目标对象+切面+接口+配置
ProxyFactory源码分析
下面依照上面测试中代码顺序依次分析
1 代理工厂
1 创建代理工厂,直接调用默认空构造器
ProxyFactory factory = new ProxyFactory();
2 目标对象
2 设置代理目标对象,将target对象封装成TargetSource对象,为什么要多此一举呢?其实封装为TargetSource的目的是为了做对象池和多例用的,也就是说每次代理都从池中获取对象。而这里我们只使用SingletonTargetSource,关于TargetSource留到后面讲解。刚刚提到这些属性都是保存在AdvisedSupport中的
// 2. 设置代理目标对象
factory.setTarget(new UserServiceImpl());
public void setTarget(Object target) {
setTargetSource(new SingletonTargetSource(target));
}
@Override
public void setTargetSource(@Nullable TargetSource targetSource) {
this.targetSource = (targetSource != null ? targetSource : EMPTY_TARGET_SOURCE);
}
3 接口
3 设置接口数组,同样保存到AdvisedSupport的属性中
// 3. 设置接口 (可以多实现)
factory.setInterfaces(new Class[]{UserService.class});
public void setInterfaces(Class<?>... interfaces) {
Assert.notNull(interfaces, "Interfaces must not be null");
// 先清空再添加
this.interfaces.clear();
for (Class<?> ifc : interfaces) {
addInterface(ifc);
}
}
public void addInterface(Class<?> intf) {
Assert.notNull(intf, "Interface must not be null");
// 校验如果不是接口则抛出异常
if (!intf.isInterface()) {
throw new IllegalArgumentException("[" + intf.getName() + "] is not an interface");
}
if (!this.interfaces.contains(intf)) {
this.interfaces.add(intf);
adviceChanged();
}
}
4 通知
4 设置Advice,前面我们说过Advice只是增强,因此我们要封装成Advisor切面才能加到AdvisedSupport的advisors集合中。而需要注意的是因为没有配置任何的Pointcut,因此将使用DefaultPointcutAdvisor进行创建
// 4. 设置增强
factory.addAdvice(new LogBeforeAdvice());
//implements AfterReturningAdvice
factory.addAdvice(new LogAfterAdvice());
@Override
public void addAdvice(Advice advice) throws AopConfigException {
int pos = this.advisors.size();
addAdvice(pos, advice);
}
@Override
public void addAdvice(int pos, Advice advice) throws AopConfigException {
Assert.notNull(advice, "Advice must not be null");
if (advice instanceof IntroductionInfo) {
// We don't need an IntroductionAdvisor for this kind of introduction:
// It's fully self-describing.
// 单独处理引介增强
addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice));
}
else if (advice instanceof DynamicIntroductionAdvice) {
// We need an IntroductionAdvisor for this kind of introduction.
// DynamicIntroductionAdvice只能作为IntroductionAdvisor的一部分
throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor");
}
else {
// 普通增强
addAdvisor(pos, new DefaultPointcutAdvisor(advice));
}
}
@Override
public void addAdvisor(int pos, Advisor advisor) throws AopConfigException {
if (advisor instanceof IntroductionAdvisor) {
validateIntroductionAdvisor((IntroductionAdvisor) advisor);
}
addAdvisorInternal(pos, advisor);
}
private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException {
Assert.notNull(advisor, "Advisor must not be null");
if (isFrozen()) {
throw new AopConfigException("Cannot add advisor: Configuration is frozen.");
}
if (pos > this.advisors.size()) {
throw new IllegalArgumentException(
"Illegal position " + pos + " in advisor list with size " + this.advisors.size());
}
this.advisors.add(pos, advisor);
updateAdvisorArray();
adviceChanged();
}
而DefaultPointcutAdvisor的意思就是无论什么方法都匹配,因此可以看到Pointcut使用的是Pointcut.TRUE,无论匹配什么方法都是true
new DefaultPointcutAdvisor(advice)
// Pointcut.TRUE
// 也就是说该Advisor的匹配均为true,匹配任何的方法,不做任何限制!
public DefaultPointcutAdvisor(Advice advice) {
this(Pointcut.TRUE, advice);
}
5代理
5 创建代理,这才是本篇的重头戏
// 5. 获取代理对象
UserService userService = (UserService) factory.getProxy();
public Object getProxy() {
return createAopProxy().getProxy();
}
代码就createAopProxy().getProxy()一句,在调用getProxy()之前,我们得弄清楚是什么对象调用的getProxy(),换句话说,也就是createAopProxy()到底创建了什么对象
- UserService userService = (UserService) factory.getProxy();
- factory.getProxy(){ createAopProxy().getProxy(); }
- createAopProxy() :给工厂传入代理配置
- getAopProxyFactory().createAopProxy(this);
- getAopProxyFactory():返回this.aopProxyFactory;
- createAopProxy(this):判断进行jdk动态代理还是cglib代理
- getAopProxyFactory().createAopProxy(this);
- getProxy():创建代理对象
- createAopProxy() :给工厂传入代理配置
- factory.getProxy(){ createAopProxy().getProxy(); }
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 先获取工厂,再创建代理 // 传入工厂
return getAopProxyFactory().createAopProxy(this);
}
---------------------------------------------------------
public AopProxyFactory getAopProxyFactory() {
// 返回的是类中的成员变量aopProxyFactory
return this.aopProxyFactory;
}
---------------------------------------------------------
// 成员变量的实例化则是在默认构造器中
private AopProxyFactory aopProxyFactory;
// 构造器,调用了DefaultAopProxyFactory进行实例化,因此aopProxyFactory真正的类型是DefaultAopProxyFactory
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
跟踪发现createAopProxy()返回的是属性aopProxyFactory,而属性aopProxyFactory又是在ProxyCreatorSupport构造器时进行实例化的,真正的类是DefaultAopProxyFactory,因此继续跟踪DefaultAopProxyFactory的createAopProxy方法
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
// 利用工厂创建代理
@Override// 传入的config是工厂,工厂的父类中有代理的各种信息
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// isOptimize开启激进模式 || proxyTargetClass=true(强制开启cglib代理) || 接口集合为空
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
// 目标对象为接口,一般不会发生
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 没有接口,只能选择cglib代理
return new ObjenesisCglibAopProxy(config);
}
else {
// 使用JDK代理
return new JdkDynamicAopProxy(config);
}
}
...
}
可以看到,当config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)为真时才会使用Cglib代理,而当代理对象有实现接口,并且没有强制开启cglib代理时默认使用的是JDK代理,也就是JdkDynamicAopProxy类。
也就是说,最后将调用的其实是new JdkDynamicAopProxy(config).getProxy(),结合Jdk动态代理底层源码的内容,可以预想到有2个需要特别关注的方法。getProxy和invoke方法
// JdkDynamicAopProxy.java
@Override // 创建代理对象
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 获取代理接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 判断接口是否又hashCode和equals方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 使用JDK代理(classLoader, 接口, 当前JdkDynamicAopProxy对象:用于回调invoke和target对象方法)
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
- createAopProxy是创建好代理的各种信息
- getProxy是创建代理对象
可以看出,其实每个知识点都是关联在一起的,ProxyFactory作为Spring AOP的核心,使用的也是我们学习过的Jdk动态代理来实现的。结合第一篇Jdk动态代理底层源码的内容,最最重要的便是getProxy和invoke方法,下一节我们将进行JdkDynamicAopProxy中getProxy和invoke方法的源码剖析