本文剖析 Spring AOP 和动静代理原理和实现,Spring 版本: 5.2.3.RELEASE
动静代理
1.1 代理模式
代理模式也叫做委托模式,它是一种根本的设计模式,其作用是提供委派角色以管制对实在对象的拜访。典型的代理模式通常蕴含一下三类角色
- 形象角色:它的作用是定义一组行为规范。形象角色个别出现为接口或抽象类
- 实在角色:也叫做被委托角色、被代理角色
- 代理角色:也叫做委托类,代理角色须要实现形象角色所定义的行为(即代理类须要实现形象角色所定义的接口),并且在实现接口办法的时候须要调用实在角色的相应办法
动态代理类依赖于实在类,对每一个实在类作代理都须要对应一个代理类,动态代理大量应用会导致类的急剧收缩,区别于动态代理在编译期确定代理类和实在类的关系并且生成代理类。动静代理则是在运行期利用 JVM 的反射机制生成代理类的字节码,并通过类加载器载入执生成代理对象
1.2 JDK 动静代理
JDK 动静代理是在运行时借助 Proxy 工具类静态方法创立实现了一组特定接口的代理类和对象,Proxy 类是所有被创立的动静代理类的父类,每一个动静代理对象都会与特定的 InvocationHandler 对象绑定,对任意代理对象实现的接口办法的调用都会最终委派给 InvocationHandler#invoke 办法
// 定义形象角色接口
public interface Subject {void sayHello(String name);
}
// 接口实现
public class RealSubject implements Subject {
@Override
public void sayHello(String name){System.out.println("hello,"+ name);
}
}
// 编写调用解决类,实现 invoke 办法(加强逻辑的入口)public class MyInvocationHandler implements InvocationHandler {
private Subject subject;
MyInvocationHandler(Subject subject){this.subject = subject;}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
// 前置解决
System.out.println("Before method invoke...");
Object obj = method.invoke(subject, args);
// 后置解决
System.out.println("After method invoke...");
return obj;
}
}
// 测试方法
public class Client{public static void main(String[] args) {Subject realSubject = new RealSubject();
MyInvocationHandler handler = new MyInvocationHandler(realSubject);
Subject proxy = (Subject)Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(), handler);
proxy.sayHello("world");
}
运行后果:Before method invoke...
hello, world
After method invoke...
从运行后果能够看出,对代理对象办法的调用会进入到自定义 MyInvocationHandler#invoke 办法,并在指标办法执行前后打印出了日志。将 Proxy 类生成的代理类通过反编译失去如下类文件,能够看到 RealSubjectProxy 继承自 Proxy 且实现了 Subject 接口,它定义了 4 个办法 m0,m1,m2,m3,其中办法 m3 是对 Subject 接口 sayHello 办法的实现
public final class RealSubjectProxy extends Proxy implements Subject {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public RealSubjectProxy(InvocationHandler var1) throws {super(var1);
}
// 代理办法
public final void sayHello(String var1) throws {
try {
// 将办法解决委派给父类 InvocationHandler#invoke 办法
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);
}
}
static {
try {//m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("com.example.demo.proxy.Subject").getMethod("sayHello", 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());
}
}
}
// Proxy 类带参构造函数
public class Proxy implements java.io.Serializable {
protected InvocationHandler h;
protected Proxy(InvocationHandler h) {Objects.requireNonNull(h);
this.h = h;
}
}
Proxy 类对外提供了 4 个静态方法,别离为
public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces);
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h);
public static boolean isProxyClass(Class<?> cl);
public static InvocationHandler getInvocationHandler(Object proxy);
newProxyInstance 通过给定类加载器和接口生成代理对象
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});
}
// 省略
}
getProxyClass 获取代理类对象
public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException {final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
return getProxyClass0(loader, intfs);
}
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {if (interfaces.length > 65535) {throw new IllegalArgumentException("interface limit exceeded");
}
// 如果缓存蕴含给定类加载器创立并且实现了特定接口的代理类,则返回该代理类;否则动态创建此代理类对象
return proxyClassCache.get(loader, interfaces);
}
1.2 Cglib 动静代理
JDK 动静代理尽管简略易用,然而其只能对实现了接口的类进行代理,而 CGLIB 以继承的形式动静生成一个被代理类的子类为没有实现接口的类提供代理,为 JDK 的动静代理提供了很好的补充。CGLIB 原理是底层应用了 ASM 来操作字节码生成新的类,子类重写被代理的类的所有非 final 的办法。在子类中通过办法拦截器拦挡所有父类办法的调用,织入横切逻辑解决。// 定义 Target 类
public class Subject {
public void sayHello() {System.out.println("hello, world!");
}
}
// 定义方法拦截器
public class LogInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable{System.out.println("before ...");
Object result = methodProxy.invokeSuper(object, args);
System.out.println("after ...");
return result;
} }
public class CglibClient {
public static void main(String[] args) {Enhancer enhancer = new Enhancer();
// 设置超类,Cglib 通过继承实现
enhancer.setSuperclass(Subject.class);
// 设置办法拦截器回调援用,对于代理类上所有办法的调用,都会调用 CallBack,而 Callback 则须要实现 intercept() 办法进行拦挡
enhancer.setCallback(new LogInterceptor());
// 创立 cglib 代理类
Subject proxy = (Subject)enhancer.create();
proxy.sayHello();}
}
控制台输入:
before …
hello, world!
after …Cglib 动静代理对象生成 Enhancer 是 CGLIB 的字节码增强器,代理类创立入口在 Enhancer#create 办法,生成代理类的二进制字节码文件;加载二进制字节码,生成 Class 对象;通过反射机制取得实例结构器并创立代理类对象,在实例化代理类对象时执行动态代码块创立 MethodProxypublic Object create() {
classOnly = false;
argumentTypes = null;
return createHelper();}
private Object createHelper() {validate();
if (superclass != null) {
// 设置生成类的名称
setNamePrefix(superclass.getName());
} else if (interfaces != null) {
// 设置生成类的名称
setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
}
// 生成代理类对象(AbstractClassGenerator#newInstance 办法中生成代理类的二进制字节码文件以及加载二进制字节码)return super.create(KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
ReflectUtils.getNames(interfaces),
filter,
callbackTypes,
useFactory,
interceptDuringConstruction,
serialVersionUID));
}Cglib 创立代理对象会产生如下 3 个 Class 文件
首先来看 Cglib 生成的代理类 Subject$$EnhancerByCGLIB$$bc785f22.class,代理类在实例化时会执行其静态方法块,期间会给代理类的成员办法创立一个 MethdProxy 对象,比方办法 CGLIB$sayHello$0 与 CGLIB$sayHello$0$Proxy,MethdProxy 会在拦截器履行被调用 public class Subject$$EnhancerByCGLIB$$bc785f22 extends Subject implements Factory {private MethodInterceptor CGLIB$CALLBACK_0; // 拦截器 private static final Method CGLIB$sayHello$0$Method; // 指标办法 private static final MethodProxy CGLIB$sayHello$0$Proxy; // 代理办法 // … 省略 static void CGLIB$STATICHOOK1() {// 加载生成的代理类 Class 对象 Class var0 = Class.forName(“com.example.demo.proxy.cglib.Subject$$EnhancerByCGLIB$$bc785f22”); // 指标类(Subject)Class 对象 Class var1; // 通过反射获取指标类办法 sayHello CGLIB$sayHello$0$Method = ReflectUtils.findMethods(new String[]{“sayHello”, “()V”}, (var1 = Class.forName(“com.example.demo.proxy.cglib.Subject”)).getDeclaredMethods())[0]; // 创立 MethodProxy CGLIB$sayHello$0$Proxy = MethodProxy.create(var1, var0, “()V”, “sayHello”, “CGLIB$sayHello$0”); } // 在拦截器中执行 methodProxy.invokeSuper 会进入这里 final void CGLIB$sayHello$0() { super.sayHello(); } public final void sayHello() { MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (this.CGLIB$CALLBACK_0 == null) {CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0; } if (var10000 != null) {var10000.intercept(this, CGLIB$sayHello$0$Method, CGLIB$emptyArgs, CGLIB$sayHello$0$Proxy); } else {super.sayHello(); } } // … 省略 }创立 MethdProxy 对象剖析,次要是实例化 MethodProxy 和 CreateInfo 对象,CreateInfo 用于拦截器执行时创立 FastClass 实例 public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
MethodProxy proxy = new MethodProxy();
// 指标类 sayHello 办法签名
proxy.sig1 = new Signature(name1, desc);
// 代理类 CGLIB$sayHello$0 办法签名
proxy.sig2 = new Signature(name2, desc);
// 创立 createInfo(CreateInfo 是 MethodProxy 的一个外部类),用来保留类等信息
proxy.createInfo = new CreateInfo(c1, c2);
return proxy;
}
private static class CreateInfo {
// 指标类 Subject
Class c1;
// 代理类 Subject$$EnhancerByCGLIB$$bc785f22
Class c2;
NamingPolicy namingPolicy;
GeneratorStrategy strategy;
boolean attemptLoad;
public CreateInfo(Class c1, Class c2) {
this.c1 = c1;
this.c2 = c2;
AbstractClassGenerator fromEnhancer = AbstractClassGenerator.getCurrent();
if (fromEnhancer != null) {namingPolicy = fromEnhancer.getNamingPolicy();
strategy = fromEnhancer.getStrategy();
attemptLoad = fromEnhancer.getAttemptLoad();}
}
}FastClass 机制在讲代理对象办法执行流程前先理解一下 Cglib 的 FastClass 机制,它的原理简略来说就是为代理类和被代理类各生成一个 Class,这个 Class 会为代理类或被代理类的办法调配一个 index,在办法执行阶段,FastClass 机制能够利用办法 index 间接定位要调用的办法进行调用,省去了反射调用,所以从调用效率上会比 JDK 动静代理通过反射调用高。之前生成的 class 文件中 Subject$$EnhancerByCGLIB$$bc785f22$$FastClassByCGLIB$$c5058ad4 就是代理类的 FastClass,而 Subject$$FastClassByCGLIB$$a84ac285 就是指标类的 FastClass。public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
//FastClass 并不是跟代理类一块生成的,而是在第一次执行 MethodProxy invoke/invokeSuper 时生成的并放在了缓存中。this.init();
MethodProxy.FastClassInfo fci = this.fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException var4) {throw var4.getTargetException();
}
}
private static class FastClassInfo {
FastClass f1;// 指标类 FastClass
FastClass f2;// 代理类 FastClass
int i1; // 指标类办法 index
int i2;// 代理类办法 index
private FastClassInfo() {
}
}
/MethodProxy invoke/invokeSuper 都调用了 init()
private void init() {if(this.fastClassInfo == null) {
Object var1 = this.initLock;
synchronized(this.initLock) {if(this.fastClassInfo == null) {
MethodProxy.CreateInfo ci = this.createInfo;
MethodProxy.FastClassInfo fci = new MethodProxy.FastClassInfo();
fci.f1 = helper(ci, ci.c1);// 如果缓存中就取出,没有就生成新的 FastClass
fci.f2 = helper(ci, ci.c2);
fci.i1 = fci.f1.getIndex(this.sig1);// 获取办法的 index
fci.i2 = fci.f2.getIndex(this.sig2);
this.fastClassInfo = fci;
this.createInfo = null;
}
}
}
}代理对象办法执行流程剖析调用代理对象 sayHello 办法 → 调用对应的办法拦截器(LogInterceptor) → methodProxy.invokeSuper → 进入代理类 CGLIB$sayHello$0 办法 → 指标类 sayHello 办法
public class Subject$$EnhancerByCGLIB$$bc785f22 extends Subject implements Factory {
private MethodInterceptor CGLIB$CALLBACK_0; // 拦截器
private static final Method CGLIB$sayHello$0$Method; // 被代理办法
private static final MethodProxy CGLIB$sayHello$0$Proxy; // 代理办法
static void CGLIB$STATICHOOK1() {
// 加载生成的代理类 Class 对象
Class var0 = Class.forName("com.example.demo.proxy.cglib.Subject$$EnhancerByCGLIB$$bc785f22");
// 指标类 Class 对象
Class var1;
// 通过反射获取被代理办法 sayHello
CGLIB$sayHello$0$Method = ReflectUtils.findMethods(new String[]{“sayHello”, “()V”}, (var1 = Class.forName(“com.example.demo.proxy.cglib.Subject”)).getDeclaredMethods())[0];
// 创立 MethodProxy
CGLIB$sayHello$0$Proxy = MethodProxy.create(var1, var0, "()V", "sayHello", "CGLIB$sayHello$0");
}
// 在拦截器中调用 methodProxy.invokeSuper 会进入这里
final void CGLIB$sayHello$0() {super.sayHello();
}
public final void sayHello() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
// 判断拦截器是否为空,不为空调用拦截器 intercept 办法
if (var10000 != null) {
// @param this 代理对象自身
// @param CGLIB$sayHello$0$Method Subject 类 sayHello 办法 Method 对象【动态代码块已赋值】// @param CGLIB$emptyArgs Subject 类 sayHello 办法参数
// @param CGLIB$sayHello$0$Proxy Subject 类 sayHello 办法的代理办法对象【动态代码块已赋值, 即 CGLIB$sayHello$0 办法】
var10000.intercept(this, CGLIB$sayHello$0$Method, CGLIB$emptyArgs, CGLIB$sayHello$0$Proxy);
} else {super.sayHello();
}
}
// … 省略
}
接下来,在 LogInterceptor 的 intercept 办法中调用的 MethodProxy#invokeSuper 时,最终就会执行父类 Subject#sayHello 办法。MethodProxy#invokeSuper 的执行逻辑如下 public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
//FastClass 对象并不是跟代理类对象一块生成的,而是在第一次执行 MethodProxy invoke/invokeSuper 时生成的并放在了缓存中。init();
FastClassInfo fci = fastClassInfo;
// 执行代理类对象 CGLIB$sayHello$0 办法
return fci.f2.invoke(fci.i2, obj, args);
}
catch (InvocationTargetException e) {throw e.getTargetException();
}
}
private void init()
{if (fastClassInfo == null)
{synchronized (initLock)
{if (fastClassInfo == null)
{
// 获取代理类的创立信息【下面有提过】CreateInfo ci = createInfo;
// 新建 FastClassInfo 对象
FastClassInfo fci = new FastClassInfo();
// 生成指标类对应 FastClass 对象
fci.f1 = helper(ci, ci.c1);
// 生成代理类对应 FastClass 对象
fci.f2 = helper(ci, ci.c2);
// 依据办法签名,获取指标类中对应 sayHello 办法在 f1 中的索引
fci.i1 = fci.f1.getIndex(sig1);
// 依据办法签名,获取代理类中对应 CGLIB$sayHello$0 办法在 f2 中的索引
fci.i2 = fci.f2.getIndex(sig2);
fastClassInfo = fci;
createInfo = null;
}
}
}
}
/*
- FastClassInfo 也是 MethodProxy 的一个外部类
*/
private static class FastClassInfo {
FastClass f1;// 指标类 FastClass
FastClass f2;// 代理类 FastClass
int i1; // 指标类 sayHello 办法 index
int i2;// 代理类 CGLIB$sayHello$0 办法 index
private FastClassInfo() {}
}二、Spring AOPAOP(Aspect Orient Programming),个别称为面向切面编程,作为面向对象的一种补充,用于解决零碎中散布于各个模块的横切关注点,比方事务管理、日志、缓存等等。SpringAOP 则是 Spring 提供的一个规范易用的 aop 框架,依靠 Spring 的 IOC 容器,提供了极强的 AOP 扩大加强能力,SpringAOP 的实现依附其底层采纳的 JDK/CGLIB 动静代理。2.1 AOP 外围概念术语含意 Aspect 申明切面,相似于类定义,每个 Aspect 能够蕴含多个 PointCut 和 AdvicePointCut 切点,用来筛选须要在哪些地位做加强解决 Joinpoint 连接点,通过 PointCut 筛选进去执行加强的节点,如办法被调用时、异样抛出时等 Advice 连接点处执行的加强逻辑 Target Object 指标对象,被织入 Advice 的对象 Weaving 将 Advice 织入到连接点的处理过程,织入可在编译时实现(例如应用 AspectJ 编译器),而 Spring AOP 在运行时实现织入解决为了标准化 AOP,Spring 引入了一套 AOP 顶级 API(AOP 联盟),用来定义和应用 AOP。spring-aop jar 包中有个目录 org.aopalliance,其中存在几个接口是 AOP 联盟提供的规范 AOP 的 API
2.2 SpringAOP 与 AOP 联盟关系
2.3 SpringAOP 的实现思路在讲 Spring AOP 外围组件概念前,咱们首先通过一个例子直观上了解 Spring AOP 外围组件作用原理。应用 Spring AOP 的关键在于配置获取 Advisor,在 Spring 2.0 版本之前定义 Advisor 是通过实现 Advisor 接口(或者 IntroductionAdvisor),定义拦截器和拦挡规定(切点)。应用 SpringAOP 大体流程为以下 3 点:配置获取 Advisor:定义拦截器(Advice)+ 拦挡规定(切点),生成 Advisor 生成代理:依据 Advisor 生成代理对象,会生成 JdkDynamicAopProxy 或 CglibAopProxy 办法执行:执行代理办法时从 Advisor 取出 Advice 转换为 MethodInvocation(连接点),执行拦截器调用 // 定义一个 Service 及实现
public interface DemoService {
}
public class DemoServiceImpl implements DemoService {
@Override
public void echo() {
System.out.println("Echo method invoke...");
}
}
// 自定义 PointCut,用于筛选 DemoService 的 echo 办法
public class DemoPointCut implements Pointcut {
@Override
public ClassFilter getClassFilter() {return new ClassFilter() {
@Override
public boolean matches(Class<?> clazz) {return DemoService.class.isAssignableFrom(clazz);
}
};
}
@Override
public MethodMatcher getMethodMatcher() {return new MethodMatcher() {
@Override
public boolean matches(Method method, Class<?> targetClass) {return "echo".equals(method.getName());
}
@Override
public boolean isRuntime() {return false;}
@Override
public boolean matches(Method method, Class<?> targetClass, Object... args) {return false;}
};
}
}
// 实现 Advice 接口减少横切逻辑
public class LogInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("Before method invoke ...");
return invocation.proceed();}
}
// 自定义 Advisor
public class DemoAdvisor implements PointcutAdvisor {
@Override
public Advice getAdvice() {return new LogInterceptor ();
}
@Override
public Pointcut getPointcut() {return new DemoPointCut();
}
@Override
public boolean isPerInstance() {return false;}
}
// 测试方法
public static void main(String[] args) {
ProxyFactory proxyFactory = new ProxyFactory(new DemoService());
proxyFactory.addAdvisor(new DemoAdvisor());
// 生成代理对象
DemoService proxy = (DemoService)proxyFactory.getProxy();
proxy.echo();
}
// 控制台输入:
Before method invoke …
Echo method invoke…
下面的例子是通过自定义实现 API 的模式来配置创立 Advisor,当然咱们也能够借助 Spring AOP 的内置实现,并把对象交由 Spring 来治理,让 Spring 容器帮咱们主动生成代理对象,Spring AOP 提供了很多类来帮忙实现主动创立代理对象,它们有一个独特的父类 AbstractAutoProxyCreator,AbstractAutoProxyCreator 具体的创立过程前面再剖析。这里咱们应用 DefaultAdvisorAutoProxyCreator 演示, 下面的 Demo 能够改为如下模式,变动根本不大 public class AutoProxyConfig {
@Bean
public DemoService echoService() {return new DemoServiceImpl();
}
@Bean
public LogInterceptor logInterceptor() {return new LogInterceptor();
}
@Bean
public Advisor advisor() {NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor();
advisor.setMappedName("echo");
advisor.setAdvice(logInterceptor());
return advisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator autoProxyCreator() {return new DefaultAdvisorAutoProxyCreator();
}
}
测试方法:
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AutoProxyConfig.class);
// 获取代理对象
DemoService demoService = context.getBean(DemoService.class);
demoService.echo();
}
控制台输入:
Before method invoke …
Echo method invoke… 当 Spring 2.0 公布当前,Spring AOP 集成了 AspectJ 减少了新的应用形式,即通过 AspectJ 注解形式(如 @Aspect 和 @Around)定义 Aspect 和 Adivce, 然而 Spring AOP 只是引入了其注解性能(提供注解驱动的 AOP),底层的实现和织入形式还是 1.x 原先的实现体系。下面的 Demo 能够改为如下模式,这也是当初咱们应用 AOP 最罕用的模式 @Aspect
@Component
public class LogAspect {
@Pointcut(value = "execution(* com.example.demo.service..*.*(..))")
public void pointCut() {}
@Before("pointCut()")
public void logStart(JoinPoint joinPoint){System.out.println("Before method invoke ...");
}
}2.4 外围组件概念 2.4.1 Advice 告诉(增强器)顶级接口,通过 PointCut 筛选出 Jointpoint 时,咱们就须要在这些 Jointpoint 上减少横切逻辑,这些横切逻辑被称为 Advice。Advice 次要分成两类一般 Advice 与 Interceptor/MethodInterceptor,无论通过 aop 命名空间 /AspectJ 注解正文的办法, 其最终都将解析成对应的 Advice,所有的 Advice 会在最终代理办法执行阶段转换适配成 MethodInterceptor 被执行
应用 AspectJ 注解定义切面时罕用到的五个注解,每个注解会别离被包装为以下 Advice, 它们实际上是对以上 Advice 的实现
2.4.2 InterceptorInterceptor 是继承自 Advice 的两头接口,它示意以拦截器形式实现加强成果,Interceptor 得子接口有两个:MethodInterceptor 和 ConstructorInterceptor,然而 Spring 没有提供 ConstructorInterceptor 的实现类,而 MethodInterceptor 则示意通过拦挡办法的执行来实现加强成果,上述基于 AspectJ 注解对应的五个 Advice,实质上都是实现了 MethodInterceptor(或者在执行阶段被转换为 MethodInterceptor),比方实现盘绕告诉 Advice 类 (AspectJAroundAdvice) 就实现了 MethodInterceptor
前置告诉 AspectJMethodBeforeAdvice 没有实现 MethodInterceptor,然而会在执行阶段被包装为 MethodBeforeAdviceInterceptor,执行包装的是 MethodBeforeAdviceAdapter
2.4.3 Jointpoint 通过 Pointcut 筛选出须要加强解决的中央就是 Jointpoint。在办法执行阶段能够通过 Joinpoint 实现类中获取增强器等信息,比方应用 Cglib 生成代理对象,在代理办法执行时就是通过 CglibMethodInvocation(Joinpoint 实现)取得拦截器(MethodInterceptor)并链式执行。在 AOP 理念中很多中央能够减少横切逻辑,如办法执行,字段设置等。Spring 目前只反对办法执行这一种 Joinpoint,Spring 提供的 Joinpoint 实现如下
public interface Joinpoint {
// 执行此拦挡点,并进入到下一个连接点
Object proceed() throws Throwable;
// 返回保留以后连接点动态局部,这里个别指 target 对象
Object getThis();
// 返回此动态连接点 个别就为以后的 Method
AccessibleObject getStaticPart();
}
public interface Invocation extends Joinpoint {
// 返回办法参数
Object[] getArguments();
public interface MethodInvocation extends Invocation {
// 返回以后 Method 对象,成果同父类的 getStaticPart 办法
Method getMethod();
}SpringAOP 在 AOP Alliance 根底上减少了几个类,丰盛了 AOP 定义及应用概念,包含 Advisor:蕴含 Advice 和 PointCut,Spring 外部应用 AOP 的顶级接口 Pointcut: 匹配哪些类哪些办法须要被切面解决,蕴含一个 ClassFilter 和一个 MethodMatcherClassFilter:类过滤器,定义类过滤规定,用于筛选哪些类对象须要应用 AOPMethodMatcher:办法匹配器,定义方法匹配规定,用于筛选哪些办法须要应用 AOP2.4.4 Advisor 在 AOP 设计理念中通过 Aspect 来申明切面,每个 Aspect 能够蕴含多个 Pointcut 和 Advice。在 Spring AOP 中,Aspect 对应的实现为 Advisor。Advisor 是 Pointcut 和 Advice 的容器,然而一个 Advisor 只能蕴含一个 Pointcut 和 Advice。配置定义 Advisor 是应用 Spring AOP 的要害。public interface Advisor {
// Spring5 当前才有的空告诉,个别当作默认值
Advice EMPTY_ADVICE = new Advice() {};
// 该 Advisor 持有的告诉器
Advice getAdvice();
boolean isPerInstance();
}
Advisor 是顶级接口,然而没有给出过滤匹配切点的形式,两个次要的扩大接口 IntroductionAdvisor(引介加强)和 PointcutAdvisor,区别在 IntroductionAdviso 只能利用于类级别的拦挡,只能应用 Introduction 型的 Advice,而 PointcutAdvisor 定义了 class 类型 + 办法匹配过滤形式,能够应用任何类型的 Pointcut 以及简直任何类型的 Advice,PointcutAdvisor 性能更弱小,IntroductionAdvisor 平时较少用到,这里不做介绍,Spring 提供的 PointcutAdvisor 实现十分多,这里列举其中局部实现:PointcutAdvisor 应用场景 AspectJPointcutAdvisorSpring 解析 aop 命名空间时生成的 Advisor,对应的 Advice 是 AspectJMethodBeforeAdvice、AspectJAfterAdvice,、AspectJAfterReturningAdvice,、AspectJAfterThrowingAdvice 和 AspectJAroundAdvice,Pointcut 则是 AspectJExpressionPointcut,对于这个类的解析是在 ConfigBeanDefinitionParserInstantiationModelAwarePointcutAdvisorImplSpring 解析被 @AspectJ 正文的类时生成的 Advisor,这个 Advisor 中的 Pointcut 与 Advice 都是由 ReflectiveAspectJAdvisorFactory 来解析生成的(与之对应的 Advice 和 Pointcut 同 AspectJPointcutAdvisor),具备提早初始化策略 DefaultPointcutAdvisor Spring 提供的通用的,也被认为是最弱小的 Advisor。它能够组合任意的两个 Advice 和 PointcutBeanFactoryCacheOperationSourceAdvisorSpring 缓存注解 @Cacheable 相干 AsyncAnnotationAdvisorSpring 异步办法调用注解 @Async 相干 NameMatchMethodPointcutAdvisor 基于办法名是否匹配来执行 Advice,其中的 Pointcut 默认是 NameMatchMethodPointcutRegexpMethodPointcutAdvisor 基于正则表达式来匹配执行 Advice,其中的 Pointcut 默认是 JdkRegexpMethodPointcutBeanFactoryTransactionAttributeSourceAdvisor 在注解式事务编程时, 次要是由 BeanFactoryTransactionAttributeSourceAdvisor、AnnotationTransactionAttributeSource 和 TransactionInterceptor 组合起来进行事务的操作 2.4.5 PointCut 定义切面的匹配点,简略的说就是去切哪些类、哪些办法,在 Spring Aop 中匹配的点次要是 class 与 method,对应于为 ClassFilter 与 MethodFilterpublic interface Pointcut {
// 类过滤器, 能够晓得哪些类须要拦挡
ClassFilter getClassFilter();
// 办法匹配器, 能够晓得哪些办法须要拦挡
MethodMatcher getMethodMatcher();
// 匹配所有对象的 Pointcut
Pointcut TRUE = TruePointcut.INSTANCE;
}Spring 提供的局部 PointCut 实现列举:NameMatchMethodPointcut:基于办法名进行匹配。(其中 ClassFilter = ClassFilter.TRUE)ComposablePointcut:组合模式的 Pointcut, 次要分成两种: 1. 组合中所有都匹配算胜利 2. 组合中都不匹配才算胜利 JdkRegexpMethodPointcut:通过正则表达式来匹配办法(ClassFilter = ClassFilter.TRUE)AspectJExpressionPointcut:通过 AspectJ 包中的组件进行办法的匹配(切点表达式)TransactionAttributeSourcePointcut:Spring 注解式事务的 Pointcut。通过匹配办法上 @Transactional 标签来确定办法是否匹配 2.6 Spring AOP 主动动静代理应用 Aspectj 提供的注解定义切面,Spring 只是引入了其注解形底层的实现和织入形式还是 1.x 原先的实现体系,由 Spring 解析配置生成 Advisor,这里以在 SpringBoot 工程应用 AOP 为例阐明 Spring 是如何主动解析配置 Advisor 并生成代理对象的。这也是目前咱们应用 AOP 的罕用形式,以日志切面为例,定义 Aspect 如下整体解决流程如下 1.@EnableAspectJAutoProxy 注解会开启 AOP 性能,并在我的项目启动时往 IOC 容器中注册组件 AnnotationAwareAspectJAutoProxyCreator,它实现了 BeanPostProcessor2. AnnotationAwareAspectJAutoProxyCreator 会拦挡 Bean 的创立过程, 判断 Bean 是否须要加强,如须要就会配置包装增强器(Advisor),并借助动静代理将加强逻辑织入创立的代理对象 3. 办法执行阶段,对办法调用会被代理对象拦截器拦挡(以 Cglib 为例),执行者是 CglibAopProxy.DynamicAdvisedInterceptor#intercept 办法,在该办法中会通过代理对象中保留的增强器,指标对象等信息生成指标办法的拦截器链(行将增强器包装成拦截器 MethodInterceptor),利用拦截器的链式机制,顺次进入每一个拦截器进行执行,AnnotationAwareAspectJAutoProxyCreator 类关系图
SpringBoot 启动时 refresh 办法中调用 this.registerBeanPostProcessors(beanFactory) 实例化和注册实现了后置处理器(BeanPostProcessor)的 Bean,在初始化 AnnotationAwareAspectJAutoProxyCreator 时会调用 BeanFactoryAware 接口办法 setBeanFactory 将 BeanFactory 注入组件,同时初始化 AspectJAdvisorFactory 和 BeanFactoryAspectJAdvisorsBuilderAdapter,BeanFactoryAspectJAdvisorsBuilderAdapter 封装了工厂类 AspectJAdvisorFactory,其外围的逻辑在其办法 buildAspectJAdvisors 中,该办法查找容器中所有 @AspectJ 注解的 Bean, 而后将其中每个 advice 办法包装成 Advisor@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory:" + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}Spring Bean 创立都会进入 BeanPostProcessor 的处理过程,Spring AOP 主动配置 Advisor 并通过动静代理创立 Proxy 对象织入加强逻辑入口也正是在 AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization 办法,整体流程图
代码解决入口在 AbstractAutoProxyCreator#postProcessAfterInitialization 办法 @Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 依据须要包装 Bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {// TargetSource 是对被代理对象 target 的封装,代理对象从 TargetSource 获取 target
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 如果曾经被加强解决过,间接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}
// 判断 bean 的类型是否为根底类:Advice,Pointcut,Advisor,AopInfrastructureBean
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取办法拦截器(Advisor 汇合),如果 Advisor 不为空则创立代理对象
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创立代理对象
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}获取 Advisor 汇合办法入口(AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean)protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {return DO_NOT_PROXY;}
return advisors.toArray();}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 步骤 1. 用于获取所有的 Advisor, 包含间接配置得 Advisor 和用 AspectJ 定义的 Advisor,即把 AspectJ 定义的 bean 转化为 Advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 步骤 2. 遍历获取到的 Advisor,逐个从 Advisor 拿到 PointCut, 通过 PointCut 判断 Advisor 是否实用于以后 Bean
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 拓展 Advisor
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 对 Advisor 排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
// 步骤 1 处会进入 AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
// 获取间接配置的 Advisor, 实现 Advisor 接口的 bean 组件
List<Advisor> advisors = super.findCandidateAdvisors();
// 获取标注 @Aspect 组件的 bean,并解析 bean 标注了 @Before,@After,@AfterReturning,@AfterThrowing 的办法转换为 Advisor
if (this.aspectJAdvisorsBuilder != null) {
// aspectJAdvisorsBuilder 在注册 AnnotationAwareAspectJAutoProxyCreator 组件时生成,
// 它会在 BeanFactory 中查找带有 @Aspect 注解的 Bean, 并通过 AspectJAdvisorFactory 为每一个 Advice 办法生成一个 Advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
// 步骤 2 处 findAdvisorsThatCanApply 办法最终进入以下办法判断
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
// PointCut 中类过滤器是否匹配指标类
if (!pc.getClassFilter().matches(targetClass)) {return false;}
// 省略 ...
// 创立办法匹配器
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
// 遍历办法对象
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
// 存在某一办法匹配,则返回 true
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {return true;}
}
}
return false;
}在讲代理创立前,先理解一下 ProxyFactory,后面的例子中能够看到创立代理对象走的是 ProxyFactory.getProxy(getProxyClassLoader()), 但真正创立代理对象是通过 AopProxyFactory。ProxyFactory 继承自 ProxyCreatorSupport 和 AdvisedSupport,ProxyCreatorSupport 默认构造函数初始化了一个默认的 AopProxyFactory(即 DefaultAopProxyFactory,Spring 惟一实现),AdvisedSupport 用于保留 Advisor、指标对象和接口等属性,ProxyFactory#getProxy 办法实际上是调用了 DefaultAopProxyFactory#createAopProxy(AdvisedSupport config)
Spring Aop 创立代理对象并织入切面逻辑的入口 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()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);
}
else {evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 将须要织入的切面逻辑都转换为 Advisor 对象
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
// 提供的 hook 办法,供子类实现对代理工厂的定制
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);
}
// 生成代理类
return proxyFactory.getProxy(getProxyClassLoader());
}
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {activate();
}
// 从父类 ProxyCreatorSupport 拿到代理类工厂 DefaultAopProxyFactory,并将本身 (ProxyFactory 继承 AdvisedSupport) 作为参数传入,作为创立的代理对象属性
// AdvisedSupport 会作为后续办法执行时获取 Advisor, 指标对象和接口等结构拦截器链的起源
return getAopProxyFactory().createAopProxy(this);
}Spring AOP 生成代理对象用了工厂模式
AopProxyFactory 创立代理对象 public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 判断以后类是否须要进行运行时优化,或者是指定了应用 Cglib 代理的形式,再或者是指标类没有用户提供的相干接口,则应用 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.");
}
// 如果被代理的类是一个接口,或者被代理的类是应用 Jdk 代理生成的类,此时还是应用 Jdk 代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);
}
// 返回 Cglib 代理生成对象
return new ObjenesisCglibAopProxy(config);
} else {
// 返回 JDK 代理生成对象
return new JdkDynamicAopProxy(config);
}
}以下次要剖析应用 Cglib 形式生成代理实现代理逻辑的织入 public Object getProxy(@Nullable ClassLoader classLoader) {
try {Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
// 判断以后类是否是曾经通过 Cglib 代理生成的类,如果是的,则获取其原始父类,// 并将其接口设置到须要代理的接口中
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
// 获取父类
proxySuperClass = rootClass.getSuperclass();
// 获取父类实现的接口,并将其设置到须要代理的接口中
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {this.advised.addInterface(additionalInterface);
}
}
// 对指标类进行查看,次要检查点有三个:// 1. 指标办法不能应用 final 润饰;// 2. 指标办法不能是 private 类型的;// 3. 指标办法不能是包拜访权限的;// 这三个点满足任何一个,以后办法就不能被代理,此时该办法就会被略过
validateClassIfNecessary(proxySuperClass, classLoader);
// 创立 Enhancer 对象,并且设置 ClassLoader
Enhancer enhancer = createEnhancer();
if (classLoader != null) {enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
// 这里 AopProxyUtils.completeProxiedInterfaces()办法的次要目标是为要生成的代理类减少 SpringProxy,Advised 这两个须要实现的接口。这里两个接口的作用如下:// 1. SpringProxy:是一个空接口,用于标记以后生成的代理类是 Spring 生成的代理类;// 2. Advised:Spring 生成代理类所应用的属性都保留在该接口中,包含 Advisor,指标对象等属性;enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
// 获取代理类中各个办法将要应用的 Interceptor(这里的 Interceptor 与 aopaliance 中的 Interceptor 不是同一接口), 其中就包含(DynamicAdvisedInterceptor)
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {types[x] = callbacks[x].getClass();}
// 设置拦截器过滤器,用于筛选各个办法将要应用的 Interceptor,这里的 ProxyCallbackFilter.accept()办法返回的整型值正好一一对应下面 Callback 数组中各个拦截器的下标
enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap,
this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 生成代理对象
return createProxyClassAndInstance(enhancer, callbacks);
} catch (CodeGenerationException | IllegalArgumentException ex) {// 省略} catch (Throwable ex) {throw new AopConfigException("Unexpected AOP exception", ex);
}
}指标办法的执行代理对象创立好后,其实最终的拦挡工作都是交给了 MethodInvocation,JDK 交给 ReflectiveMethodInvocation,Cglib 交给 CglibMethodInvocation(继承自 ReflectiveMethodInvocation), 执行过程图示
这里以 Cglib 阐明执行的大体过程:对指标办法调用实际上会进入代理对象办法的执行,如后面 Cglib 动静代理局部剖析,通过 Cglib 生成代理对象的办法执行最终会进入 CglibAopProxy.DynamicAdvisedInterceptor#intercept 办法在 DynamicAdvisedInterceptor#intercept 办法中通过代理对象持有的 ProxyFactory(继承自 AdvisedSupport)将代理对象保留的 Advisor 转化为拦截器链同时结构 CglibMethodInvocation 作为拦截器链调用入口,CglibMethodInvocation 继承自 ReflectiveMethodInvocation,入口办法 proceed 实际上会进入 ReflectiveMethodInvocation#proceed 办法在 ReflectiveMethodInvocation#proceed 中获取每一个办法拦截器并执行其 invoke 办法(若以后拦截器不是最初一个),每一个拦截器会期待下一个拦截器执行实现返回当前再继续执行,在拦截器执行 invoke 办法前后执行加强解决;如果为最初一个拦截器则调用指标办法拦截器链的机制,保障加强解决办法与指标办法的执行程序
链式调用机制
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;
// 指标对象源
TargetSource targetSource = this.advised.getTargetSource();
try {if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 拿到指标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 将代理对象保留的 Advisor 转化为拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 没有增强器,同时该办法是 public 得 就间接调用指标办法(不拦挡)if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// 结构 CglibMethodInvocation 作为拦截器链调用入口并执行调用
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);
}
}
}
}