我们一直用jdk动态代理,还没有深入进去看一下,那么这篇文章就来看一下他是怎么创建动态代理的:
UserService userService = new UserServiceImpl();
UserService proxy = (UserService) Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
method.invoke(userService,args);
System.out.println("after");
return null;
}
});
proxy.add();
以上就是我们的示例代码,接下来我们就开始进入动态代理的创建过程:
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);
}
//利用我们传入的接口与和类加载器创建代理类
Class<?> cl = getProxyClass0(loader, intfs);
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//根据构造函数的参数选择一个构造函数,默认是InvocationHandler
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);
}
}
在这个方法中最重要的三件事就是:
1、利用我们传入的类加载器和接口创建代理类的class对象
2、选择一个构造函数
3、根据构造函数实例化对象
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
return proxyClassCache.get(loader, interfaces);
}
首先会从代理类的缓存中查找是否创建过当前class对象,有的话直接返回,否则再创建:
public V get(K key, P parameter) {
//对接口进行非空判断
Objects.requireNonNull(parameter);
//清除一些失效的Entry
expungeStaleEntries();
//将当前类加载器封装成一个cacheKey
Object cacheKey = CacheKey.valueOf(key, refQueue);
// 从缓存中查找由当前类加载器加载的class对象
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
//如果没有找到,说明没有找到,然后通过原子操作为当前类加载器创建一个map
if (valuesMap == null) {
ConcurrentMap<Object, Supplier<V>> oldValuesMap
= map.putIfAbsent(cacheKey,
valuesMap = new ConcurrentHashMap<>());
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}
// 通过类加载器和接口创建一个key用来定位class对象
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
//根据key查找
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
//如果找到了对应的class对象就直接返回,否则创建一个
while (true) {
//如果不为null,说明缓存中有,直接返回class对象
if (supplier != null) {
// supplier might be a Factory or a CacheValue<V> instance
V value = supplier.get();
if (value != null) {
return value;
}
}
// 创建一个class对象
if (factory == null) {
factory = new Factory(key, parameter, subKey, valuesMap);
}
//通过原子操作将当前创建的class对象放到集合中
if (supplier == null) {
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
supplier = factory;
}
} else {
if (valuesMap.replace(subKey, supplier, factory)) {
//替换旧的值
supplier = factory;
} else {
// 替换失败使用旧的值
supplier = valuesMap.get(subKey);
}
}
}
}
针对不同的类加载器会有一个Map用来存放它加载的class对象,如果缓存中有,那么直接返回,没有就会创建一个然后放到缓存里面,接下来我们看一下class对象是如何被获取到的:
public synchronized V get() { // serialize access
// 在验证一次
Supplier<V> supplier = valuesMap.get(subKey);
if (supplier != this) {
// 如果不相同返回null
return null;
}
// else still us (supplier == this)
// create new value
V value = null;
try {
//创建class对象
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
if (value == null) {
//如果创建失败移除这个元素
valuesMap.remove(subKey, this);
}
}
// the only path to reach here is with non-null value
assert value != null;
// 将当前值封装成一个缓存的值
CacheValue<V> cacheValue = new CacheValue<>(value);
//放到map里面
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;
}
}
在这里面最重要的方法就是apply:
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
//遍历所有的接口
for (Class<?> intf : interfaces) {
//重新创建当前接口的class对象
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
...
}
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
//遍历所有的接口
for (Class<?> intf : interfaces) {
//获得修饰符
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}
if (proxyPkg == null) {
// if no non-public proxy interfaces, use com.sun.proxy package
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
//为当前代理类生成一个编号
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
//生成代理类字节码文件
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
//根据字节码文件创建代理class对象
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
这个方法很长,我们关注的就只有两件事:
1、生成代理类字节码文件
2、根据字节码文件创建代理class对象
接下来就是通过反射实例化对象了。