Aop的核心原理概括起来就是代理和拦截。代理对象生成之后,当我们调用目标对象被代理的方法时,就会触发拦截器的拦截功能,从而实现增强目标对象功能的作用。拦截器对目标对象方法进行拦截的方式是回调,比如使用Jdk动态代理生成的对象都会实现InvocationHandler接口,那么就需要在回调invoke方法中实现拦截,即增强,同理如果使用Cglib的方式生成代理对象,那么实现拦截功能的就是回调方法就是intercept方法。看到此处我们会发现其实拦截器和代理对象是同一个东西,或者说代理对象中的回调方法实现了目标对象增强功能。
下面以调用addStudent方法为例,介绍Jdk动态代理方式的回调方法。
调用addStudent方法的时候,直接进入了JdkDynamicAopProxy类的invoke方法。
方法中先根据目标对象获取目标对象的class,然后根据目标对象需要代理的方法和class获取拦截器链。
这段代码逻辑很简单,先从缓存中去取拦截器链,缓存中没有再生成。
接下来便是生成拦截器链的过程。
代码config.getAdvisors()获取到的是在初始化通知器链时生成的通知器数组。
然后遍历通知器数组,在registry.getInterceptors(advisor)中,根据通知器获取里面封装的Advice对象,再将Advice封装成对应的MethodInterceptor对象,保存在集合中,生成MethodInterceptor数组。因为配置文件中没有配置切入点Point的匹配规则,所以使用默认的匹配规则。最后将MethodInterceptor数组存入集合中。通知器数组遍历完,拦截器链也就生成了。
拦截器链生成之后,就可以逐个利用拦截器实现目标对象的增强功能了。如何实现的呢?就是靠retVal = invocation.proceed()这行代码。
其中interceptorsAndDynamicMethodMatchers这个集合就传入的拦截器链。proceed()的主要功能就是逐个执行拦截器链中拦截器的方法。
以MethodBeforeAdviceInterceptor拦截器为例。在proceed()中触发了该拦截器的invoke方法。
进入before方法,我们发现执行的正是前置增强方法。
回到MethodBeforeAdviceInterceptor的invoke方法中,执行mi.proceed()方法,又回到了proceed()方法,通过这种方式可以使拦截器链里面的每个拦截器都得到执行,直到拦截器链里的拦截器执行完。
我们在使用Aop的时候看起来好像是为目标对象增加了几个功能和方法,其实质是通过Jdk动态代理或者Cglib代理的方式为目标对象生成代理对象。当调用目标对象方法的时候触发拦截器的拦截功能并逐一调用Advice中相应的方法,“增强”了目标对象的功能。
Aop源码分析之如何实现功能增强
最新推荐文章于 2023-08-22 21:09:53 发布