SpringAOP详解源码解析
SpringAOP源码解析
AOP概述
概念解析
-
连接点 JoinPoint
- CardService类中的三个方法都可以被增强(增加一些功能,比如方法调用前后的日志打印),哪些方法可以被增强,那这些方法就可以被称为连接点,所以这三个方法(add,find,edit)都可以被称为连接点。
-
切入点 PointCut
-
假如我们只增强某个方法,那这些实际被我们增强的方法就称为切入点,真正增强的方法才成为切入点,没有实际增强(可以被增强但是没有增强)的不是。比如我们指定在add方法和edit方法前后打印日志,那么切入点就是add方法和edit方法
-
对应AspectTest类中的pointCut方法上的**@Pointcut注解**
-
-
通知 Advice
-
假如我们要在add方法进行之后做一些其它操作,那我们在方法进行后添加的代码部分就称为增强(通知),也就是说实际增加的逻辑部分就称为通知。
-
对应AspectTest类中的**@AfterReturning,@Around,@After,@Before,@AfterThrowing**五个注解修饰的方法
-
-
Advisor (通知器)
-
作用:Advisor 是一个包含切入点(Pointcut)和增强(Advice)的组合,它告诉 AOP 框架在何时(切入点)以及如何(增强)干预目标对象的行为。
-
组成:一个 Advisor 通常由两部分组成:
- Pointcut(切入点):定义了在目标对象的哪些方法上应用增强。例如,可以使用表达式或注解来指定切入点。
- Advice(增强):定义了在切入点何时执行的逻辑,例如在方法执行前后、抛出异常时等。
-
-
切面 Aspect
-
切面指的是一个动作或过程,指的就是把通知应用到切入点的过程,假如我们想对add方法加上增强,我们把增强的部分加上去的过程就叫切面。
-
整个AspectTest的类被**@Aspect**注解修饰,说明这是一个切面
-
-
目标对象
- CardService类就是我们的目标对象
-
代理对象
- 将切面织入目标对象后所得到的就是代理对象。代理对象是具备通知所定义的功能和目标对象的业务功能。
-
织入
-
把切面应用到目标对象来创建新的代理对象的过程。切面的织入有三种方式
-
编译时织入(Compile-Time Weaving)
- 织入发生在源代码编译阶段。
- 需要特殊的编译器或工具来进行AOP织入。
- 修改源代码,因此需要访问源代码的权限。
- 生成的目标类已经包含了切面的逻辑,无需在运行时再次织入。
-
类加载时织入(Load-Time Weaving)
- 织入发生在类加载过程中,但在类被实际加载到内存前。
- 使用字节码增强工具(如AspectJ的LTW或Java Agent)来实现。
- 不需要修改源代码,但需要特殊的配置和启动参数来启用织入。
- 可以选择性地为某些类启用AOP织入,而不影响其他类。
-
运行时织入(Run-Time Weaving)
- 织入发生在应用程序运行时。
- 通常使用代理对象来实现AOP,代理对象在运行时动态添加切面逻辑。
- 不需要修改源代码或进行特殊的编译,更加灵活。
- 允许动态地添加、修改或删除切面,因为织入是在运行时发生的。
-
-
springAOP通常使用运行时织入(Run-Time Weaving)方式来实现。
CGLIB实现流程
源码解析
Enhancer类
概述
Enhancer 类是 CGLib 中最常用的一个类,使用 Enhancer 类生成动态子类以启用方法拦截。
相关方法
-
// 我们创建完Enhancer后,设置完SuperClass和callback之后,通过调用create方法获取生成代理子类 public Object create() { this.classOnly = false; this.argumentTypes = null; return this.createHelper(); }
-
private Object createHelper() { // 前置验证 preValidate(); // 荣国KEY_FACTORY.newInstance方法生成key Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null, ReflectUtils.getNames(interfaces), filter == ALL_ZERO ? null : new WeakCacheKey(filter), callbackTypes, useFactory, interceptDuringConstruction, serialVersionUID); this.currentKey = key; // 调用create方法开始创建代理子类,最终会调用到Enhancer的generateClass方法 Object result = super.create(key); return result; }
-
// 该方法 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())); // 去掉private之类的不能被继承的构造函数 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(); // 声明所有必须为public的方法集合 这儿主要是代理接口接口的方法 final Set forcePublic = new HashSet(); // 即通过传入的代理类,代理接口,遍历所有的方法并放入对应的集合 getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic); // 对所有代理类方法修饰符做处理 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); } }); ClassEmitter e = new ClassEmitter(v); if (currentData == null) { e.begin_class(Constants.V1_8, 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_8, 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); } 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) { emitMethods(e, methods, actualMethods); emitConstructors(e, constructorInfo); } else { emitDefaultConstructor(e); } emitSetThreadCallbacks(e); emitSetStaticCallbacks(e); emitBindCallbacks(e); 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(); }
-
protected Object create(Object key) { try { ClassLoader loader = getClassLoader(); Map cache = CACHE; ClassLoaderData data = cache.get(loader); if (data == null) { synchronized (AbstractClassGenerator.class) { cache = CACHE; data = cache.get(loader); if (data == null) { Map newCache = new WeakHashMap(cache); data = new ClassLoaderData(loader); newCache.put(loader, data); CACHE = newCache; } } } this.key = key; // 获取代理类,这里被封装为了EnhancerFactoryData类型,里面保存了代理类的ClassLoader,回调方法,主构造函数信息等。 Object obj = data.get(this, getUseCache()); if (obj instanceof Class) { return firstInstance((Class) obj); } // 这里最终会调用EnhancerFactoryData的newInstance方法,通过反射创建代理对象实例 return nextInstance(obj); } catch (RuntimeException | Error ex) { throw ex; } catch (Exception ex) { throw new CodeGenerationException(ex); } }
EnhancerFactoryData类
static class EnhancerFactoryData {
// 代理类的Class信息
public final Class generatedClass;
// 回调函数信息
private final Method setThreadCallbacks;
// 主构造函数参数列表
private final Class[] primaryConstructorArgTypes;
// 主构造函数
private final Constructor primaryConstructor;
public EnhancerFactoryData(Class generatedClass, Class[] primaryConstructorArgTypes, boolean classOnly) {
this.generatedClass = generatedClass;
try {
// 获取所有的回调,实际上就是我们自定义的实现了MethodInterceptor接口的切面
setThreadCallbacks = getCallbacksSetter(generatedClass, SET_THREAD_CALLBACKS_NAME);
if (classOnly) {
this.primaryConstructorArgTypes = null;
this.primaryConstructor = null;
}
else {
this.primaryConstructorArgTypes = primaryConstructorArgTypes;
this.primaryConstructor = ReflectUtils.getConstructor(generatedClass, primaryConstructorArgTypes);
}
}
catch (NoSuchMethodException e) {
throw new CodeGenerationException(e);
}
}
// 为给定的参数类型创建代理实例,并分配回调。理想情况下,对于每个代理类,只应使用一组参数类型,否则将不得不在构造函数查找上花费时间
public Object newInstance(Class[] argumentTypes, Object[] arguments, Callback[] callbacks) {
setThreadCallbacks(callbacks);
try {
// Explicit reference equality is added here just in case Arrays.equals does not have one
if (primaryConstructorArgTypes == argumentTypes ||
Arrays.equals(primaryConstructorArgTypes, argumentTypes)) {
// If we have relevant Constructor instance at hand, just call it
// This skips "get constructors" machinery
return ReflectUtils.newInstance(primaryConstructor, arguments);
}
// Take a slow path if observing unexpected argument types
// 通过反射创建代理类实例并返回
return ReflectUtils.newInstance(generatedClass, argumentTypes, arguments);
}
finally {
// clear thread callbacks to allow them to be gc'd
setThreadCallbacks(null);
}
}
private void setThreadCallbacks(Callback[] callbacks) {
try {
setThreadCallbacks.invoke(generatedClass, (Object) callbacks);
}
catch (IllegalAccessException e) {
throw new CodeGenerationException(e);
}
catch (InvocationTargetException e) {
throw new CodeGenerationException(e.getTargetException());
}
}
}
KeyFactory类
通过KeyFactory的create静态方法创建KeyFactroy的代理。用于后面生成代理对象唯一标识,通过唯一标识来在运行时查找和缓存代理类的实例。提高aop性能。
AbstractClassGenerator类
-
核心功能
通过asm方式生成代理类的class文件。
实现ClassGenerator接口,但没有实现接口中的generateClass方法,
-
缓存
- 在运行时,一个类或者接口并不是单单由它的名称确x的,而是由它的二进制名称以及它的定义类加载器共同确定的。每个这样的类或者接口都属于一个运行时包,运行时包则由包名和定义类加载器共同确定。上述中所谓的定义类加载器实际上就是getClassLoader()的返回值,而这个概念的产生则跟类加载过程中的“双亲委派机制”有关。当要加载一个类时,第一个发起类加载的加载器称之为“初始类加载器”(initiating loader),但是根据“双亲委派机制”,它会先将加载委派给父加载器,如果父加载器加载失败,才会最终由自己尝试加载。而无论哪个加载器加载成功,它就是该类的定义类加载器(defining class loader)。
-
ClassLoaderData静态内部类
保存ClassLoader的数据
protected static class ClassLoaderData { private final Set reservedClassNames = new HashSet(); /** * {@link AbstractClassGenerator} here holds "cache key" (e.g. {@link org.springframework.cglib.proxy.Enhancer} * configuration), and the value is the generated class plus some additional values * (see {@link #unwrapCachedValue(Object)}. * <p>The generated classes can be reused as long as their classloader is reachable.</p> * <p>Note: the only way to access a class is to find it through generatedClasses cache, thus * the key should not expire as long as the class itself is alive (its classloader is alive).</p> */ private final LoadingCache generatedClasses; /** * Note: ClassLoaderData object is stored as a value of {@code WeakHashMap} thus * this classLoader reference should be weak otherwise it would make classLoader strongly reachable * and alive forever. * Reference queue is not required since the cleanup is handled by {@link WeakHashMap}. */ private final WeakReference classLoader; private final Predicate uniqueNamePredicate = new Predicate() { public boolean evaluate(Object name) { return reservedClassNames.contains(name); } }; // 获取每个 private static final Function GET_KEY = new Function() { public Object apply(AbstractClassGenerator gen) { return gen.key; } }; public ClassLoaderData(ClassLoader classLoader) { // 判断类加载器不能为空 if (classLoader == null) { throw new IllegalArgumentException("classLoader == null is not yet supported"); } this.classLoader = new WeakReference(classLoader); // 新建一个回调函数,这个回调函数的作用在于缓存中没获取到值时,调用传入的类生成代理类并返回 Function load = new Function() { public Object apply(AbstractClassGenerator gen) { Class klass = gen.generate(ClassLoaderData.this); return gen.wrapCachedClass(klass); } }; generatedClasses = new LoadingCache(GET_KEY, load); } public ClassLoader getClassLoader() { return classLoader.get(); } public void reserveName(String name) { reservedClassNames.add(name); } public Predicate getUniqueNamePredicate() { return uniqueNamePredicate; } public Object get(AbstractClassGenerator gen, boolean useCache) { // 是否使用缓存 if (!useCache) { // 不适用缓存直接调用方法获取当前ClassLoader加载的类信息 return gen.generate(ClassLoaderData.this); } else { //直接generatedClasses中我们每次新加ClassLoaderData对象时创建的load回调函数最终调用到AbstractClassGenerator的generate获取当前ClassLoader加载的类信息 Object cachedValue = generatedClasses.get(gen); return gen.unwrapCachedValue(cachedValue); } } }
Generator(AbstractClassGenerator的实现类)
-
实现了ClassGenerator的generateClass方法。主要就是保存了当前类的ClassLoader信息和类信息以及当前的类权限保护域信息。
-
在java中,以类为单位,将不同的类分在不同的保护域。每个类加载器具有一个保护域,使用同一个类加载器加载的类在同一个保护域,也就是说具有相同的权限。java可以对不同的保护区授予不同的权限,那么这块区域中的代码(类)就会拥有所在保护区的权限。
-
在KeyFactory类内部,是一个内部类
-
实现了generateClass方法
-
public void generateClass(ClassVisitor v) { /** * 在CGLIB中,CodeEmitter类是一个核心组件,它负责生成字节码并定义类的行为。它可以理解为一个代码发射器,用于将特定的指令序列生成为目标类的字节码。 * 通过使用CodeEmitter,我们可以动态地创建新的类,或者在现有类的基础上进行扩展。 * CodeEmitter的作用可以总结如下: * 生成字节码:CodeEmitter负责将Java代码转化为字节码指令序列,这样可以在运行时动态地创建新的类或者修改现有类的行为。 * 实现动态代理:在Spring中,CGLIB通常被用于创建动态代理对象。CodeEmitter负责生成代理类的字节码,使得代理对象能够拦截目标方法的调用并执行额外的逻辑。 * 实现AOP:在AOP中,我们可以通过在目标方法的前后插入一些代码来实现对方法的增强。CodeEmitter可以用来生成拦截器,使得我们能够在目标方法执行前后添加额外的逻辑。 */ ClassEmitter ce = new ClassEmitter(v); //找到被代理类的newInstance方法。如果没有会报异常,由此可知,如果想用Generator代理类生成器,必须要有newInstance方法 Method newInstance = ReflectUtils.findNewInstance(keyInterface); //如果被代理类的newInstance不为Object则报异常,此处我们代理的Enchaer.EnhancerKey newInstance方法返回值为Object if (!newInstance.getReturnType().equals(Object.class)) { throw new IllegalArgumentException("newInstance method must return Object"); } //获取被代理类的newInstance方法的参数类型 Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes()); // 1.创建类,写入类头,版本号,访问权限,类名等通用信息 ce.begin_class(Constants.V1_8, Constants.ACC_PUBLIC, getClassName(), KEY_FACTORY, new Type[]{Type.getType(keyInterface)}, Constants.SOURCE_FILE); // 2.创建默认无参构造函数 EmitUtils.null_constructor(ce); // 3.写入newInstance方法 EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance)); int seed = 0; /** * * CodeEmitter类是CGLIB(Code Generation Library)库中的一个核心组件。它负责生成字节码并定义类的行为,允许在运行时动态地创建新的类或者修改现有类的行为。 * 具体来说,CodeEmitter类主要提供了以下功能: * 生成字节码指令序列: CodeEmitter可以将高级的Java代码转换为底层的字节码指令序列。这使得我们能够在运行时动态地生成新的类,或者在现有类的基础上进行扩展。 * 实现动态代理: 在Spring框架中,CGLIB通常用于创建动态代理对象。CodeEmitter负责生成代理类的字节码,使得代理对象能够拦截目标方法的调用并执行额外的逻辑。 * 实现AOP(面向切面编程): 在AOP中,我们可以通过在目标方法的前后插入一些代码来实现对方法的增强。CodeEmitter可以用来生成拦截器,使得我们能够在目标方法执行前后添加额外的逻辑。 */ // 4.开始构造有参构造方法 CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, TypeUtils.parseConstructor(parameterTypes), null); e.load_this(); // 开始调用父类的构造方法 e.super_invoke_constructor(); e.load_this(); // 找到传入的Customizer List fieldTypeCustomizers = getCustomizers(FieldTypeCustomizer.class); // 遍历即newInstance方法的所有参数 for (int i = 0; i < parameterTypes.length; i++) { Type parameterType = parameterTypes[i]; // 获取参数的类型 Type fieldType = parameterType; // 如果有Customizer,则对参数进行定制 for (FieldTypeCustomizer customizer : fieldTypeCustomizers) { fieldType = customizer.getOutType(i, fieldType); } seed += fieldType.hashCode(); // 为每个参数创建一个字段 ce.declare_field(Constants.ACC_PRIVATE | Constants.ACC_FINAL, getFieldName(i), fieldType, null); e.dup(); e.load_arg(i); // 如果有Customizer,则对参数进行定制 for (FieldTypeCustomizer customizer : fieldTypeCustomizers) { customizer.customize(e, i, parameterType); } e.putfield(getFieldName(i)); } // 设置方法返回值 e.return_value(); // 结束构造方法 e.end_method(); // hash code 开始写入hashCode方法 e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null); int hc = (constant != 0) ? constant : PRIMES[(Math.abs(seed) % PRIMES.length)]; int hm = (multiplier != 0) ? multiplier : PRIMES[(Math.abs(seed * 13) % PRIMES.length)]; e.push(hc); for (int i = 0; i < parameterTypes.length; i++) { e.load_this(); e.getfield(getFieldName(i)); EmitUtils.hash_code(e, parameterTypes[i], hm, customizers); } e.return_value(); e.end_method(); // equals 开始写入equals方法 e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null); Label fail = e.make_label(); e.load_arg(0); e.instance_of_this(); e.if_jump(CodeEmitter.EQ, fail); for (int i = 0; i < parameterTypes.length; i++) { e.load_this(); e.getfield(getFieldName(i)); e.load_arg(0); e.checkcast_this(); e.getfield(getFieldName(i)); EmitUtils.not_equals(e, parameterTypes[i], fail, customizers); } e.push(1); e.return_value(); e.mark(fail); e.push(0); e.return_value(); e.end_method(); // toString 开始写入toString方法 e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null); e.new_instance(Constants.TYPE_STRING_BUFFER); e.dup(); e.invoke_constructor(Constants.TYPE_STRING_BUFFER); for (int i = 0; i 0) { e.push(", "); e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING); } e.load_this(); e.getfield(getFieldName(i)); EmitUtils.append_string(e, parameterTypes[i], EmitUtils.DEFAULT_DELIMITERS, customizers); } e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING); e.return_value(); e.end_method(); // 类写入结束,至此类信息收集完成并全部写入ClassVisitor ce.end_class(); }
DefaultNamingPolicy类
默认的类名生成策略。通过getClassName方法生成代理类的类名
public String getClassName(String prefix, String source, Object key, Predicate names) {
// 如果没有类的前缀名,生成默认前缀名
if (prefix == null) {
prefix = "org.springframework.cglib.empty.Object";
} else if (prefix.startsWith("java")) {
prefix = "$" + prefix;
}
String base = prefix + "$$" + source.substring(source.lastIndexOf(46) + 1) + this.getTag() + "$$" + Integer.toHexString(STRESS_HASH_CODE ? 0 : key.hashCode());
String attempt = base;
for(int index = 2; names.evaluate(attempt); attempt = base + "_" + index++) {
}
return attempt;
}
DefaultGeneratorStrategy类
默认的字节码处理来。通过该类以ASM字节码完成对类的字节码二进制流生成
// 这是通过ASM的方式生成代理类的入口
public byte[] generate(ClassGenerator cg) throws Exception {
DebuggingClassWriter cw = this.getClassVisitor();
// 此处通过完成类的字节码生成写入cw
this.transform(cg).generateClass(cw);
// cw生成对应的二进制流
return this.transform(cw.toByteArray());
}
SpringAOP详解
代码示例
业务代码
public class CardService {
public void add() {
System.out.println("add");
}
public void find() {
System.out.println("find");
}
public void edit() {
System.out.println("edit");
}
}
切面类代码
@Aspect
@Component
public class AspectTest {
@Before("pointcut()")
public void before() {
System.out.println("before");
}
@After("pointcut()")
public void after() {
System.out.println("after");
}
@Around("pointcut()")
public void around() {
System.out.println("around");
}
@AfterReturning("pointcut()")
public void afterReturning() {
System.out.println("afterReturning");
}
@AfterThrowing("pointcut()")
public void afterThrowing() {
System.out.println("afterThrowing");
}
@Pointcut("execution(* circulate.*.test(..))")
public void pointcut() {
}
}
切面解析流程
AbstractAutowireCapableBeanFactory的createBean方法
AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation方法(这里会调用所有的InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation 这是入口一)
AbstractAutoProxyCreator的postProcessBeforeInstantiation方法
AnnotationAwareAspectJAutoProxyCreator的findCandidateAdvisors方法,获取所有的Advisor
BeanFactoryAspectJAdvisorsBuilder的buildAspectJAdvisors方法开始处理所有@Aspectj注解修饰的类
ReflectiveAspectJAdvisorFactory的getAdvisors方法
ReflectiveAspectJAdvisorFactory的getAdvisor方法(重载方法)
InstantiationModelAwarePointcutAdvisorImp的构造方法
InstantiationModelAwarePointcutAdvisorImp的instantiateAdvice方法,这里根据注解类型不同生成五种不同的通知(Advice)和Pointcut切面
ReflectiveAspectJAdvisorFactory的getAdvice方法,这里根据注解类型不同生成五种不同的通知(Advice)和Pointcut切面
五种切面通知
- before,after,around,afterReturn,afterThrowing分别对应AspectJMethodBeforeAdvice,AspectJAfterAdvice,AspectJAroundAdvice,AspectJAfterReturningAdvice,AspectJAfterThrowingAdvice。五种不同的通知
- 所有的方法通知调用都是通过invoke方法(实现MethodInterceptor接口覆写invoke方法)定义实现。但并不是所有的Advice都有invoke方法。其中AspectJAfterThrowingAdvice,AspectJAfterAdvice,AspectJAroundAdvice实现了MethodInterceptor接口。
- AspectJMethodBeforeAdvice和AspectJAfterReturningAdvice没有实现MethodInterceptor接口,需要通过DefaultAdvisorAdapterRegistry类通过adapter转换为MethodInterceptor接口的实现类,以便进行链式调用。(AspectJAfterReturningAdvice--AfterReturningAdviceInterceptor AspectJMethodBeforeAdvice-MethodBeforeAdviceInterceptor)
- 为什么有的直接实现了MethodInterceptor接口,有的没有直接实现MethodInterceptor接口,需要我们通过adapter进行一次转换。AspectJMethodBeforeAdvice和AspectJAfterReturningAdvice这两个方法分别在目标方法调用之前和目标方法返回的时候调用。没有直接实现应该是方便我们进行二次扩展开发,实现自定义逻辑。
创建代理
AbstractAutoProxyCreator的createProxy方法
protected Object createProxy(Class beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 设置代理工厂的属性
proxyFactory.copyFrom(this);
// 如果需要直接代理目标类
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
// 如果当前beanClass是jdk动态代理类,则需要将其接口添加到代理工厂中
if (Proxy.isProxyClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
for (Class ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// No proxyTargetClass flag enforced, let's apply our default checks...
// 判断是否需要代理当前类,如果需要设置proxyTargetClass为true,后面会判断proxyTargetClass是否为true,如果为true则根据targetClass是否为Interface来决定走jdk还是cglib代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 添加代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 构建所有已经解析到Advisor通知器列表advisors
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 将advisors放入代理工厂
proxyFactory.addAdvisors(advisors);
// targetSource就是符合条件,需要被代理增强的类
proxyFactory.setTargetSource(targetSource);
// 定制代理工厂
customizeProxyFactory(proxyFactory);
// 控制代理工程被配置之后,是否还允许修改通知,默认值是false
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
// 获取代理工厂的类加载器
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 创建并获取真正的代理对象
return proxyFactory.getProxy(classLoader);
}
public Object getProxy(@Nullable ClassLoader classLoader) {
// 这里会调用CglibAopProxy的getProxy方法
return createAopProxy().getProxy(classLoader);
}
CglibAopProxy的getProxy方法
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 获得目标类的Class对象
Class rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
// 记录被代理类的Class对象
Class proxySuperClass = rootClass;
// 如果当前目标类是CGLIB生成的代理类,则获取其父类,即目标类
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class[] additionalInterfaces = rootClass.getInterfaces();
for (Class additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
// 校验目标类的方法
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
// 创建CGLIB Enhancer对象
Enhancer enhancer = createEnhancer();
// 设置classLoader
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);
// 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);
}
}
CglibAopProxy的getCallbacks方法
通过getCallbacks方法,获取到rootClass所有符合条件切面回调方法。并生成一个Callback数组callbacks
private Callback[] getCallbacks(Class rootClass) throws Exception {
// Parameters used for optimization choices...
// 是否暴露代理对象
boolean exposeProxy = this.advised.isExposeProxy();
// 是否冻结
boolean isFrozen = this.advised.isFrozen();
// boolean isFrozen = true;
// 目标类是否是静态的
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
/**
* 将生成DynamicAdvisedInterceptor,这个拦截器是用来处理AOP调用的,它持有了AdvisedSupport对象,也就是我们定义的所有的Advisor
* 很重要,后面生成字节码之后,会在相应的方法之后插入这个拦截器,也就是说,所有符合条件的方法前后都会插入这个 DynamicAdvisedInterceptor这个类的intercept方法,会根据我们定义的Advisor,来决定调用哪些advice
*/
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
// 如果暴露代理对象
if (exposeProxy) {
// 如果需要提前暴露代理对象,根据是否是静态的目标类,创建不同的拦截器,然后放入到ThreadLocal中,方便当前线程获取
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
// 如果不需要暴露代理对象,根据是否是静态的目标类,创建不同的拦截器
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
// 创建一个直接调用目标类的拦截器
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal 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),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
/**
* 如果目标类是静态的,并且代理对象已经冻结,说明我们不会再修改代理对象
* 那么我们可以通过使用固定的拦截器链,将AOP调用直接发送到目标类,从而进行一些优化
*/
if (isStatic && isFrozen) {
// 获取目标类的method列表
Method[] methods = rootClass.getMethods();
// 创建一个固定的拦截器数组
Callback[] fixedCallbacks = new Callback[methods.length];
// 创建一个固定的拦截器map,记录方法名和下标
this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
// 遍历目标类方法列表,根据我们设置的切面配置,为每个方法创建一个拦截器链,这个拦截器链里面保存了所有符合条件的advice
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
这个callbacks数组的第一个元素就是CglibAopProxy的内部类DynamicAdvisedInterceptor。在通过字节码写入的时候讲这个类织入了生成后的代理类的目标方法中。
public final Integer add(Integer var1, Integer var2) {
// 给var10000赋值。这是一个MethodInterceptor
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
// 如果此时var10000为null。初始化CGLIB$CALLBACK_0。再次赋值
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
// 如果var10000不为空。调用var10000的intercept方法。这个var10000实际上就是DynamicAdvisedInterceptor
return var10000 != null ? (Integer)var10000.intercept(this, CGLIB$add$0$Method, new Object[]{var1, var2}, CGLIB$add$0$Proxy) : super.add(var1, var2);
}
这动态代理生成后的add方法(add为自定义方法)。可以看到首先将this.CGLIBCALLBACK0赋值给var10000,如果var10000是null。调用CGLIBCALLBACK_0赋值给var10000,如果var10000是null。调用CGLIBCALLBACK0赋值给var10000,如果var10000是null。调用CGLIBBIND_CALLBACKS方法初始化CGLIB$CALLBACK_0。然后再次赋值给var10000。
CGLIBBINDCALLBACKS方法完成对CGLIBBIND_CALLBACKS方法完成对CGLIBBINDCALLBACKS方法完成对CGLIBCALLBACK_0一直到CGLIBCALLBACK6完成赋值。这里var10000是CGLIBCALLBACK_6完成赋值。这里var10000是CGLIBCALLBACK6完成赋值。这里var10000是CGLIBSTATIC_CALLBACKS,实际上就是上面截图中的callbacks。
核心数据结构-栈
整个切面执行流程,就是先把所有符合条件的Advisor有序的入栈,入栈之后然后依次出栈,在出栈过程中完成通过反射调用Advisor定义的增强逻辑,最终完成切面整个调用过程。
核心类
DynamicAdvisedInterceptor aop代理的入口
- spring容器启动之后,再调用符合代理方法时会进入这个intercept方法进行代理处理。
- 最重要的步骤是List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 获取拦截器处理链。然后根据拦 截器链完成切面处理。
- DynamicAdvisedInterceptor类代码
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
// 获取当前线程的代理对象
boolean setProxyContext = false;
// 目标对象
Object target = null;
// 获取目标对象的Class对象
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
// 获取目标对象
target = targetSource.getTarget();
// 获取目标对象的Class对象
Class targetClass = (target != null ? target.getClass() : null);
// 获取方法的拦截器链。非常关键,后面就是在这个chain拦截链上完成对目标方法的切面处理。
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
// 如果拦截器链为空,并且方法是public的,那么可以直接调用目标对象的方法,不需要创建MethodInvocation
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 获取参数列表
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
// 创建一个CglibMethodInvocation对象,这个对象持有了目标对象,目标类,方法,参数,拦截器链等信息,用于调用目标方法,这里最终会调用到ReflectiveMethodInvocation的proceed方法
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
@Override
public boolean equals(@Nullable Object other) {
return (this == other ||
(other instanceof DynamicAdvisedInterceptor &&
this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));
}
/**
* CGLIB uses this to drive proxy creation.
*/
@Override
public int hashCode() {
return this.advised.hashCode();
}
}
- 生成拦截器链的核心方法(DefaultAdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法)
@Override
public List 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.
// 这里用了一个单例模式 获取DefaultAdvisorAdapterRegistry实例
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 获取所有的Advisor通知期
Advisor[] advisors = config.getAdvisors();
// 用于存放拦截器链
List interceptorList = new ArrayList(advisors.length);
// 获取目标类,如果目标类不为空,则使用目标类,否则使用方法所在的类
Class actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
// 遍历所有的Advisor
for (Advisor advisor : advisors) {
// 如果是PointcutAdvisor类型的,就是通过切点来进行匹配的
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;
//检测Advisor是否适用于此目标方法。这里会根据切面表达式的不同,来使用不同的匹配器
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
// 如果匹配的话,就将Advisor转换为MethodInterceptor
if (match) {
// 通过AdvisorAdapterRegistry中注册的AdvisorAdapter对Advisor进行转换
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));
}
}
}
}
// 如果是IntroductionAdvisor类型的,就是通过IntroductionAdvisor来进行匹配的
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;
}
CglibMethodInvocation 开始进入代理处理流程
- CglibMethodInvocation类代码
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
@Nullable
private final MethodProxy methodProxy;
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
Object[] arguments, @Nullable Class targetClass,
List interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
// 这里直接调用了ReflectiveMethodInvocation的构造方法
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
// Only use method proxy for public methods not derived from java.lang.Object
// 这是只处理不是从java.lang.Object派生的公共方法使用方法代理
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
methodProxy : null);
}
@Override
@Nullable
public Object proceed() throws Throwable {
try {
// 这里调用了ReflectiveMethodInvocation的proceed方法,实际上最终是ReflectiveMethodInvocation完成了方法的调用
return super.proceed();
}
catch (RuntimeException ex) {
throw ex;
}
catch (Exception ex) {
if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) ||
KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) {
// Propagate original exception if declared on the target method
// (with callers expecting it). Always propagate it for Kotlin code
// since checked exceptions do not have to be explicitly declared there.
throw ex;
}
else {
// Checked exception thrown in the interceptor but not declared on the
// target method signature -> apply an UndeclaredThrowableException,
// aligned with standard JDK dynamic proxy behavior.
throw new UndeclaredThrowableException(ex);
}
}
}
/**
* 完成目标方法的调用
*/
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.methodProxy != null) {
return this.methodProxy.invoke(this.target, this.arguments);
}
else {
return super.invokeJoinpoint();
}
}
}
- CglibMethodInvocation是一个静态内部类,位于CglibAopProxy中。继承ReflectiveMethodInvocation。CglibMethodInvocation的主要功能就是对ReflectiveMethodInvocation进行了包装,实例化ReflectiveMethodInvocation。并调用ReflectiveMethodInvocation的相关方法。
ReflectiveMethodInvocation 完成代理的链式调用
- 因为在CglibMethodInvocation的构造方法里面调用了ReflectiveMethodInvocation的构造方法,所以ReflectiveMethodInvocation实例持有完成代理调用的很多信息,包括interceptorsAndDynamicMethodMatchers拦截器链(实际上就是DynamicAdvisedIntercept的intercept方法的List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)获取的chain数组),目标方法参数等关键信息。所以能够完成chain的链式调用
- 在proceed()方法中找到当前要调用的拦截器,通过反射((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this)完成Advisor的拦截调用时,将当前对象传入了调用对象的MethodInteceptor中。而当前对象持有了拦截器链,目标对象等关键信息才能完成链式调用。
- 比如下面这个AspectJAfterAdvice,我们通过反射调用invoke方法时,invoke方法的参数MethodInvocation实际上就是ReflectiveMethodInvocation实例。铜在invoke方法中调用mi.prceed()之后最终又会回到ReflectiveMethodInvocation的prceed()方法。在进入ReflectiveMethodInvocation的prceed()方法之后会通过currentInterceptorIndex这个索引下标位置来判断是否完成拦截器链的所有拦截器调用。如果没有完成则进入下一个拦截器调用。
- 对于aroundAdvice环绕通知,在定义方法时有一个ProceedingJoinPoint类型参数pjp,并在方法内部调用pjp.proceed(); 在AspectJAroundAdvice中,实际上ProceedingJoinPoint里面包含了ReflectiveMethodInvocation实例。所以调用pjp.proceed()方法仍会进入ReflectiveMethodInvocation的proceed继续查找下一个拦截器链完成调用。