上篇文章分析了CGLIB创建代理的逻辑结构,但是感觉CGLIB比JDK生成代理复杂很多,而且上篇文章没有深入,本文将深入了解 CGLIB创建过程,本文包含包含CGLIB创建代理的逻辑代码有点多,但是确实复杂!
总不能Spring 替我们生成了类,而我们不知道它具体长啥样子吧。
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
此为Spring中代理方法创建入口。
CglibAopProxy
直接进入CglibAopProxy主工具类,入口是 getProxy
方法:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// advised 为一个辅助类,里面包含了当前该bean类所命中的所有advice等,rootClass即代理原始类。
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
// 以当前rootClass为父类进行创建
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
// 验证当前类,例如final类型方法无法创建代理,包可见的无法创建代理因为ClassLoader不同
validateClassIfNecessary(proxySuperClass, classLoader);
// 创建Enhancer并配置
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
// 设置classLoader
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 设置父类,如果proxySuperClass 是接口,则会将其作为接口设置
enhancer.setSuperclass(proxySuperClass);
// 设置接口类,AopProxyUtils.completeProxiedInterfaces(this.advised) 中会获取所有匹配的接口类,以及其他类,例如 SpringProxy、Advised
// DecoratingProxy 等
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
// 设置Spring 生成代理的命名规则,就是我们所常见的 $$BySpringCGLIB 之类
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
// 设置字节码生成策略器,这里设置为 ClassLoaderAwareUndeclaredThrowableStrategy,为对 DefaultGeneratorStrategy 一层封装
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
// 获取各种回调
Callback[] callbacks = getCallbacks(rootClass);
// 设置callbacks的Class类型
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
// 设置CallBackFilter的值
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
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);
}
}
以下为总结核心步骤:
- 由于CGLIB是通过子类方式,故会获取当前代理类,并且会检查所有方法,对于final类型不能重写方法,会输出
debug
类型日志。 - 设置Interfaces,会通过
AopProxyUtils.completeProxiedInterfaces(this.advised)
,利用AdvisedSupport
获取该bean类型,所需要所有待实现的接口,通过配置可以加入SpringProxy
、Advised
,DecoratingProxy
等内置接口,当然也可以像jdk代理一样加入自定义接口。例如使用IntroductionAdvisor
拓展bean功能。 - 设置代理类命名模式
SpringNamingPolicy
和 ClassLoader包装工具类ClassLoaderAwareUndeclaredThrowableStrategy
。 - 配置并设置回调类
Callback
。最后主要会返回以下几种类型callback,可以理解为CGLIB代理类,代理各种方法策略:
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // DynamicAdvisedInterceptor 类型,拦截正常 advice切面
targetInterceptor, // 直接调用方法,不走拦截器 invoke target without considering advice, if optimized
new SerializableNoOp(), // 没有重写任何方法,则会匹配该像no override for methods mapped to this
targetDispatcher,
this.advisedDispatcher,
new EqualsInterceptor(this.advised), // 处理equals
new HashCodeInterceptor(this.advised) // 处理hashcode
};
- 设置一个
ProxyCallbackFilter
,用于对 上述callbacks进行过滤,封装具体需要拦截的逻辑。
createProxyClassAndInstance
这样就会调用到了子类 ObjenesisCglibAopProxy
的 createProxyClassAndInstance
方法,实际上还是主要功能还是有Enhancer
完成,因为Enhancer
负责画一个类,而Objenesis
只是负责创建类实例。
// Enhance 负责画一个类
Class<?> proxyClass = enhancer.createClass();
Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try {
// 创建类实例
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
}
catch (Throwable ex) {
logger.debug("Unable to instantiate proxy using Objenesis, " +
"falling back to regular proxy construction", ex);
}
}
createClass
主要就来看Spring 集成的Cglib 是如何利用 Enhancer 和 ASM创建,来替我们创建一个代理类。
public Class createClass() {
classOnly = true;
return (Class) createHelper();
}
而后进入 createHelper
:
private Object createHelper() {
// 前置验证callbackTypes 和 filter
preValidate();
// 创建一个包装工具类
Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
ReflectUtils.getNames(interfaces),
filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter),
callbackTypes,
useFactory,
interceptDuringConstruction,
serialVersionUID);
this.currentKey = key;
// 调用父类 AbstractClassGenerator 的create方法
Object result = super.create(key);
return result;
}
本步包括以下几个步骤:
- 验证callbackTypes 和 filter
- 利用 代理类名字和回调callback创建包装类
- 调用父类 AbstractClassGenerator 的create方法
AbstractClassGenerator 的 create
看看create关键代码:
protected Object create(Object key) {
try {
// 获取classloader
ClassLoader loader = getClassLoader();
Map<ClassLoader, ClassLoaderData> cache = CACHE;
// 尝试从缓存中获取ClassLoader相关存储信息
ClassLoaderData data = cache.get(loader);
if (data == null) {
synchronized (AbstractClassGenerator.class) {
cache = CACHE;
data = cache.get(loader);
if (data == null) {
Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
data = new ClassLoaderData(loader);
newCache.put(loader, data);
CACHE = newCache;
}
}
}
this.key = key;
// 将this穿进去,此时this就是Enhancer
Object obj = data.get(this, getUseCache());
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
return nextInstance(obj);
}
...
- 获取ClassLoader和 ClassLoaderData。
- 调用
ClassLoaderData
,并调用其 get方法,传入当前实例即Enhancer
和 代表是否用索引的useCache
看ClassLoaderData
的get方法:
public Object get(AbstractClassGenerator gen, boolean useCache) {
if (!useCache) {
return gen.generate(ClassLoaderData.this);
}
else {
Object cachedValue = generatedClasses.get(gen);
return gen.unwrapCachedValue(cachedValue);
}
}
如果不使用缓存,则直接会调用 Enhancer
的 generate
方法进行生成。
如果使用缓存,则会从 LoadingCache<AbstractClassGenerator, Object, Object>
获取,而最终也会通过 Enhancer
的 generate
创建。
LoadingCache
是Spring 通过字节码生成的。
LoadingCache 的get方法
public V get(K key) {
KK cacheKey = this.keyMapper.apply(key);
Object v = this.map.get(cacheKey);
return v != null && !(v instanceof FutureTask) ? v : this.createEntry(key, cacheKey, v);
}
如果获取不到,则会进入createEntry进行创建:
protected V createEntry(final K key, KK cacheKey, Object v) {
boolean creator = false;
FutureTask task;
Object result;
if (v != null) {
task = (FutureTask)v;
} else {
// 封装成为一个异步task进行使用
task = new FutureTask(new Callable<V>() {
public V call() throws Exception {
return LoadingCache.this.loader.apply(key);
}
});
result = this.map.putIfAbsent(cacheKey, task);
if (result == null) {
creator = true;
// 调用run方法,即调用 `LoadingCache.this.loader.apply(key);` 方法
task.run();
} else {
if (!(result instanceof FutureTask)) {
return result;
}
task = (FutureTask)result;
}
}
try {
// 阻塞获取结果
result = task.get();
} catch (InterruptedException var9) {
throw new IllegalStateException("Interrupted while loading cache item", var9);
} catch (ExecutionException var10) {
Throwable cause = var10.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException)cause;
}
throw new IllegalStateException("Unable to load cache item", cause);
}
if (creator) {
this.map.put(cacheKey, result);
}
return result;
}
上面主要有以下几个逻辑:
- 声明一个FutureTask进行代理类创建。
- key 其实就是 一个Enhancer类型
- 最终就是异步调用
LoadingCache.this.loader.apply(key);
方法,而LoadingCache的loader长这个样子:
public ClassLoaderData(ClassLoader classLoader) {
if (classLoader == null) {
throw new IllegalArgumentException("classLoader == null is not yet supported");
}
this.classLoader = new WeakReference<ClassLoader>(classLoader);
Function<AbstractClassGenerator, Object> load =
new Function<AbstractClassGenerator, Object>() {
public Object apply(AbstractClassGenerator gen) {
// gen 就是Enhancer
Class klass = gen.generate(ClassLoaderData.this);
return gen.wrapCachedClass(klass);
}
};
generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
}
所以在异步方法中,其实就是调用 Enhancer
的 generate
方法。
Enhancer 的 generate
看Enhancer 的generate:
@Override
protected Class generate(ClassLoaderData data) {
// 验证classOnly 和 callbacks等字段
validate();
if (superclass != null) {
// 设置名字前缀
setNamePrefix(superclass.getName());
}
else if (interfaces != null) {
// 如果superClass == null,设置接口包可见的一个接口名字作为前缀
setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
}
// 调用父类generate方法
return super.generate(data);
}
父类 AbstractClassGenerator
的 generate
方法:
protected Class generate(ClassLoaderData data) {
Class gen;
Object save = CURRENT.get();
// 设置当前执行threadlocal
CURRENT.set(this);
try {
// 获取当前threadLoader
ClassLoader classLoader = data.getClassLoader();
if (classLoader == null) {
throw new IllegalStateException("ClassLoader is null while trying to define class " +
getClassName() + ". It seems that the loader has been expired from a weak reference somehow. " +
"Please file an issue at cglib's issue tracker.");
}
synchronized (classLoader) {
// 获取创建之后的class名字
String name = generateClassName(data.getUniqueNamePredicate());
data.reserveName(name);
this.setClassName(name);
}
if (attemptLoad) {
// 是否直接返回,没有封装回调及aop,只是用cglib生成一个对象。
try {
gen = classLoader.loadClass(getClassName());
return gen;
}
catch (ClassNotFoundException e) {
// ignore
}
}
// 使用上面定义的策略即asm生成类的字节码
byte[] b = strategy.generate(this);
String className = ClassNameReader.getClassName(new ClassReader(b));
ProtectionDomain protectionDomain = getProtectionDomain();
synchronized (classLoader) { // just in case
// SPRING PATCH BEGIN
gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain, contextClass);
// SPRING PATCH END
}
return gen;
}
catch (RuntimeException | Error ex) {
throw ex;
}
catch (Exception ex) {
throw new CodeGenerationException(ex);
}
finally {
CURRENT.set(save);
}
}
上面有以下逻辑:
- 设置当前实例到CURRENT的ThreadLocal变量中。
- 通过ThreadLoader获取待生成的class名字。
- 判断是否是直接返回,直接返回就只是生成一个类实例,而不进行自定义aop或者其他代理逻辑构建。
- 进入上面传入的策略
ClassLoaderAwareUndeclaredThrowableStrategy
的generate
进入生成字节码操作。
public byte[] generate(ClassGenerator cg) throws Exception {
if (this.classLoader == null) {
return super.generate(cg);
}
Thread currentThread = Thread.currentThread();
ClassLoader threadContextClassLoader;
try {
threadContextClassLoader = currentThread.getContextClassLoader();
}
catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
return super.generate(cg);
}
// 设置当前线程的ContextClassLoader
boolean overrideClassLoader = !this.classLoader.equals(threadContextClassLoader);
if (overrideClassLoader) {
currentThread.setContextClassLoader(this.classLoader);
}
try {
return super.generate(cg);
}
finally {
if (overrideClassLoader) {
// Reset original thread context ClassLoader.
currentThread.setContextClassLoader(threadContextClassLoader);
}
}
}
上面generate
主要是封装一层,用于设置classLoader行为。因为 ClassLoaderAwareUndeclaredThrowableStrategy
构建时已传入ClassLoader
,如果当前线程的classLoader和已有的不一致,就会用已有的classLoader替代当前线程的ClassLoader。
看ClassLoaderAwareUndeclaredThrowableStrategy
继承结构图:
而目前 generate
将会进入DefaultGeneratorStrategy
中:
public byte[] generate(ClassGenerator cg) throws Exception {
// 获取一个 DebuggingClassWriter
DebuggingClassWriter cw = this.getClassVisitor();
// 调用 当前类的 transform 类的generatateClass
this.transform(cg).generateClass(cw);
return this.transform(cw.toByteArray());
}
- 获取一个
DebuggingClassWriter
- 调用
transform
方法,实际当前类ClassLoaderAwareUndeclaredThrowableStrategy
没有改方法,则去看它的父类,发现在UndeclaredThrowableStrategy
有对父类的transform进行重写:
protected ClassGenerator transform(ClassGenerator cg) throws Exception {
ClassTransformer tr = new UndeclaredThrowableTransformer(this.wrapper);
ClassTransformer tr = new MethodFilterTransformer(TRANSFORM_FILTER, tr);
return new TransformingClassGenerator(cg, tr);
}
所以最终调用到了 TransformingClassGenerator
的 generateClass
方法:
public void generateClass(ClassVisitor v) throws Exception {
this.t.setTarget(v);
this.gen.generateClass(this.t);
}
- 此时设置ClassTransformer 的 target,target为 DebuggingClassWriter类型。
- gen为Enhancer,就会进入generateClass方法,利用asm和cglib主要就在这里面
最终,使用ClassTransformer
封装,而由Enhancer具体调用获取类型信息
public void generateClass(ClassVisitor v) throws Exception {
// 获取父类
Class sc = (superclass == null) ? Object.class : superclass;
// final 类型不能进行代理
if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException("Cannot subclass final class " + sc.getName());
// 获取构造方法
List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
// 过滤一层,只保留可见的构造方法
filterConstructors(sc, constructors);
// Order is very important: must add superclass, then
// its superclass chain, then each interface and
// its superinterfaces.
List actualMethods = new ArrayList();
List interfaceMethods = new ArrayList();
final Set forcePublic = new HashSet();
// 将interface中所有方法,获取、处理后,全部放到actualMethods 、interfaceMethods 、forcePublic 中
getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
// 将 actualMethods 中方法,经过层转化?
List methods = CollectionUtils.transform(actualMethods, new Transformer() {
public Object transform(Object value) {
Method method = (Method) value;
int modifiers = Constants.ACC_FINAL
| (method.getModifiers()
& ~Constants.ACC_ABSTRACT
& ~Constants.ACC_NATIVE
& ~Constants.ACC_SYNCHRONIZED);
if (forcePublic.contains(MethodWrapper.create(method))) {
modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
}
return ReflectUtils.getMethodInfo(method, modifiers);
}
});
// 声明cglib 类构造器
ClassEmitter e = new ClassEmitter(v);
if (currentData == null) {
e.begin_class(Constants.V1_2, // 版本
Constants.ACC_PUBLIC, // 访问性
getClassName(), // 类名
Type.getType(sc), // 父类名
(useFactory ?
TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) :
TypeUtils.getTypes(interfaces)), // 接口
Constants.SOURCE_FILE); // 类文件地址
}
else {
e.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
null,
new Type[]{FACTORY},
Constants.SOURCE_FILE);
}
List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
// 声明字段
e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null);
e.declare_field(Constants.ACC_PUBLIC | Constants.ACC_STATIC, FACTORY_DATA_FIELD, OBJECT_TYPE, null);
if (!interceptDuringConstruction) {
e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, Type.BOOLEAN_TYPE, null);
}
e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null);
e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null);
if (serialVersionUID != null) {
e.declare_field(Constants.PRIVATE_FINAL_STATIC, Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID);
}
// 有多少callback,就声明多少字段
for (int i = 0; i < callbackTypes.length; i++) {
e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null);
}
// This is declared private to avoid "public field" pollution
e.declare_field(Constants.ACC_PRIVATE | Constants.ACC_STATIC, CALLBACK_FILTER_FIELD, OBJECT_TYPE, null);
if (currentData == null) {
// 如果从未构造过,则使用actualMethods分别构造 方法和构造器
emitMethods(e, methods, actualMethods);
// 构造构造方法
emitConstructors(e, constructorInfo);
}
else {
emitDefaultConstructor(e);
}
// 构造threadCallback方法
emitSetThreadCallbacks(e);
// 构造 STATIC_CALLBACKS_FIELD 方法
emitSetStaticCallbacks(e);
// 构造 BIND_CALLBACKS
emitBindCallbacks(e);
// 构造其他callback
if (useFactory || currentData != null) {
int[] keys = getCallbackKeys();
emitNewInstanceCallbacks(e);
emitNewInstanceCallback(e);
emitNewInstanceMultiarg(e, constructorInfo);
emitGetCallback(e, keys);
emitSetCallback(e, keys);
emitGetCallbacks(e);
emitSetCallbacks(e);
}
e.end_class();
}
Enhancer 中generateClass 方法主要是构造类的框架,例如声明类,可见性设置,参数,再就是对每个方法进行判断拦截处理:
if (currentData == null) {
emitMethods(e, methods, actualMethods);
emitConstructors(e, constructorInfo);
}
而后,在emitMethods 方法中,则会对每个方法进行过滤并判断.
private void emitMethods(final ClassEmitter ce, List methods, List actualMethods) {
CallbackGenerator[] generators = CallbackInfo.getGenerators(callbackTypes);
// 声明变量
Map groups = new HashMap();
final Map indexes = new HashMap();
final Map originalModifiers = new HashMap();
final Map positions = CollectionUtils.getIndexMap(methods);
final Map declToBridge = new HashMap();
Iterator it1 = methods.iterator();
Iterator it2 = (actualMethods != null) ? actualMethods.iterator() : null;
// 遍历所有methods
while (it1.hasNext()) {
MethodInfo method = (MethodInfo) it1.next();
Method actualMethod = (it2 != null) ? (Method) it2.next() : null;
// 判断方法类型,此时filter就是 开始传入的 ProxyCallbackFilter
int index = filter.accept(actualMethod);
if (index >= callbackTypes.length) {
throw new IllegalArgumentException("Callback filter returned an index that is too large: " + index);
}
// 将方法和对应方法类型暂存起来
originalModifiers.put(method, (actualMethod != null ? actualMethod.getModifiers() : method.getModifiers()));
// 将方法和对应索引类型存起来
indexes.put(method, index);
List group = (List) groups.get(generators[index]);
if (group == null) {
// 存一份gerators和list,即将所有方法分类,存对应类型的多种方法
groups.put(generators[index], group = new ArrayList(methods.size()));
}
group.add(method);
// Optimization: build up a map of Class -> bridge methods in class
// so that we can look up all the bridge methods in one pass for a class.
if (TypeUtils.isBridge(actualMethod.getModifiers())) {
// 对编译器自动生成的桥接方法处理
Set bridges = (Set) declToBridge.get(actualMethod.getDeclaringClass());
if (bridges == null) {
bridges = new HashSet();
declToBridge.put(actualMethod.getDeclaringClass(), bridges);
}
bridges.add(method.getSignature());
}
}
final Map bridgeToTarget = new BridgeMethodResolver(declToBridge, getClassLoader()).resolveAll();
Set seenGen = new HashSet();
// 存threadLocal?
CodeEmitter se = ce.getStaticHook();
se.new_instance(THREAD_LOCAL);
se.dup();
se.invoke_constructor(THREAD_LOCAL, CSTRUCT_NULL);
se.putfield(THREAD_CALLBACKS_FIELD);
final Object[] state = new Object[1];
// 构造一份自己的 CallbackGenerator.Context
CallbackGenerator.Context context = new CallbackGenerator.Context() {
public ClassLoader getClassLoader() {
return Enhancer.this.getClassLoader();
}
public int getOriginalModifiers(MethodInfo method) {
return ((Integer) originalModifiers.get(method)).intValue();
}
public int getIndex(MethodInfo method) {
return ((Integer) indexes.get(method)).intValue();
}
public void emitCallback(CodeEmitter e, int index) {
emitCurrentCallback(e, index);
}
public Signature getImplSignature(MethodInfo method) {
return rename(method.getSignature(), ((Integer) positions.get(method)).intValue());
}
public void emitLoadArgsAndInvoke(CodeEmitter e, MethodInfo method) {
// If this is a bridge and we know the target was called from invokespecial,
// then we need to invoke_virtual w/ the bridge target instead of doing
// a super, because super may itself be using super, which would bypass
// any proxies on the target.
Signature bridgeTarget = (Signature) bridgeToTarget.get(method.getSignature());
if (bridgeTarget != null) {
// checkcast each argument against the target's argument types
for (int i = 0; i < bridgeTarget.getArgumentTypes().length; i++) {
e.load_arg(i);
Type target = bridgeTarget.getArgumentTypes()[i];
if (!target.equals(method.getSignature().getArgumentTypes()[i])) {
e.checkcast(target);
}
}
e.invoke_virtual_this(bridgeTarget);
Type retType = method.getSignature().getReturnType();
// Not necessary to cast if the target & bridge have
// the same return type.
// (This conveniently includes void and primitive types,
// which would fail if casted. It's not possible to
// covariant from boxed to unbox (or vice versa), so no having
// to box/unbox for bridges).
// TODO: It also isn't necessary to checkcast if the return is
// assignable from the target. (This would happen if a subclass
// used covariant returns to narrow the return type within a bridge
// method.)
if (!retType.equals(bridgeTarget.getReturnType())) {
e.checkcast(retType);
}
}
else {
e.load_args();
e.super_invoke(method.getSignature());
}
}
public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) {
CodeEmitter e = EmitUtils.begin_method(ce, method);
if (!interceptDuringConstruction &&
!TypeUtils.isAbstract(method.getModifiers())) {
Label constructed = e.make_label();
e.load_this();
e.getfield(CONSTRUCTED_FIELD);
e.if_jump(CodeEmitter.NE, constructed);
e.load_this();
e.load_args();
e.super_invoke();
e.return_value();
e.mark(constructed);
}
return e;
}
};
// 对对应callbackTypes遍历并生成方法
for (int i = 0; i < callbackTypes.length; i++) {
CallbackGenerator gen = generators[i];
if (!seenGen.contains(gen)) {
seenGen.add(gen);
// 获取该类型的所有方法
final List fmethods = (List) groups.get(gen);
if (fmethods != null) {
try {
// 调用对应CallbackGenerator 生成方法
gen.generate(ce, context, fmethods);
gen.generateStatic(se, context, fmethods);
}
catch (RuntimeException x) {
throw x;
}
catch (Exception x) {
throw new CodeGenerationException(x);
}
}
}
}
// 设置返回值
se.return_value();
se.end_method();
- 声明变量
- 遍历所有,将方法对应类型匹配出来,这个类型就是上面callbackTypes。
- 将第二步中匹配的信息暂存起来
- 构造
CallbackGenerator.Context
,工创建方法使用 - 遍历 callbackTypes ,调用它们的generate方法进行方法构建。
这里的CallbackType 就是开始传入的多种CallbackGenrator:
ProxyCallbackFilter
整个生成方法流程已大致走完,获取aop方法时,有通过 ProxyCallbackFilter
对方法类型进行判断:
int index = filter.accept(actualMethod);
进而看
public int accept(Method method) {
if (AopUtils.isFinalizeMethod(method)) {
logger.trace("Found finalize() method - using NO_OVERRIDE");
return NO_OVERRIDE;
}
if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
if (logger.isTraceEnabled()) {
logger.trace("Method is declared on Advised interface: " + method);
}
return DISPATCH_ADVISED;
}
// We must always proxy equals, to direct calls to this.
if (AopUtils.isEqualsMethod(method)) {
if (logger.isTraceEnabled()) {
logger.trace("Found 'equals' method: " + method);
}
return INVOKE_EQUALS;
}
// We must always calculate hashCode based on the proxy.
if (AopUtils.isHashCodeMethod(method)) {
if (logger.isTraceEnabled()) {
logger.trace("Found 'hashCode' method: " + method);
}
return INVOKE_HASHCODE;
}
Class<?> targetClass = this.advised.getTargetClass();
// Proxy is not yet available, but that shouldn't matter.
List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
boolean haveAdvice = !chain.isEmpty();
boolean exposeProxy = this.advised.isExposeProxy();
boolean isStatic = this.advised.getTargetSource().isStatic();
boolean isFrozen = this.advised.isFrozen();
if (haveAdvice || !isFrozen) {
// If exposing the proxy, then AOP_PROXY must be used.
if (exposeProxy) {
if (logger.isTraceEnabled()) {
logger.trace("Must expose proxy on advised method: " + method);
}
return AOP_PROXY;
}
String key = method.toString();
// Check to see if we have fixed interceptor to serve this method.
// Else use the AOP_PROXY.
if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(key)) {
if (logger.isTraceEnabled()) {
logger.trace("Method has advice and optimizations are enabled: " + method);
}
// We know that we are optimizing so we can use the FixedStaticChainInterceptors.
int index = this.fixedInterceptorMap.get(key);
return (index + this.fixedInterceptorOffset);
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Unable to apply any optimizations to advised method: " + method);
}
return AOP_PROXY;
}
}
else {
// See if the return type of the method is outside the class hierarchy of the target type.
// If so we know it never needs to have return type massage and can use a dispatcher.
// If the proxy is being exposed, then must use the interceptor the correct one is already
// configured. If the target is not static, then we cannot use a dispatcher because the
// target needs to be explicitly released after the invocation.
if (exposeProxy || !isStatic) {
return INVOKE_TARGET;
}
Class<?> returnType = method.getReturnType();
if (targetClass != null && returnType.isAssignableFrom(targetClass)) {
if (logger.isTraceEnabled()) {
logger.trace("Method return type is assignable from target type and " +
"may therefore return 'this' - using INVOKE_TARGET: " + method);
}
return INVOKE_TARGET;
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Method return type ensures 'this' cannot be returned - " +
"using DISPATCH_TARGET: " + method);
}
return DISPATCH_TARGET;
}
}
}
本方法主要判断方法类型,而对于是否有切面方法,则是通过AdvisedSupport
的 getInterceptorsAndDynamicInterceptionAdvice
,原理就是对每个命中的advisor进行遍历判断,如果符合则有切面:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
// 优先取缓存
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
// 委托给AdvisorChainFactory 搜寻
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
而再看 AdvisorChainFactory
的 getInterceptorsAndDynamicInterceptionAdvice
方法:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
// 遍历所有advisor
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
总结
当创建代理后,如果有aop类型,则会先进入DynamicAdvisedInterceptor 的intercept方法中,具体可以看博主上篇文章。
整个Spring 使用 CGLIB 创建代理走下来,其实,博主也没完全懂,估计就懂个20%吧。但是感觉博主跟Spring Aop CGLIB是朋友了,熟悉了,已有想扩展,或者排查问题,再进来看代码,也认识呀。
觉得博主写的有用,不妨关注博主公众号: 六点A君。
哈哈哈,一起研究Spring: