Spring AOP 流程

来源:互联网 发布:csgo mac 国服 知乎 编辑:程序博客网 时间:2024/05/18 02:47
proxy实例化
1. 根据是否有interface准备proxy:JdkDynamicAopProxy.getProxy()/CglibAopProxy.getProxy()

JDK:

public Object getProxy(ClassLoader classLoader) {if (logger.isDebugEnabled()) {logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());}Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}

其中InvocationHandler就是JdkDynamicAopProxy本身


CGLIB:

protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {enhancer.setInterceptDuringConstruction(false);enhancer.setCallbacks(callbacks);return (this.constructorArgs != null ?enhancer.create(this.constructorArgTypes, this.constructorArgs) :enhancer.create());}

 其中Callback[] 是CglibAopProxy静态内部类,有多个


共通:最重要的属性是AdvisedSupport advised; 可以想象为PointcutAdvisor的仓库


proxy方法调用

2. CGLIB调用MethodInterceptor.intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)

    JDK调用InvocationHandler.invoke(Object proxy, Method method, Object[] args)

Step1: 得到当前method对应的advice调用链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Step2: 
chain.isEmpty()==true: 直接调用target的对应method
chain.isEmpty()==false: 调用advice的invoke(MethodInvocation invocation) 在方法中可以通过invocation.proceed();继续调用chain的对应的下一个advice直到target。


Note:

1.

Spring的AOP实现可能是对JDK动态代理的妥协,让CGLIB的callback模拟JDK的InvocationHandler持有当前的target。正是因为Spring实现中最终都是调用的target的method,因此Spring的proxy方法调用自己的其他方法时不会触发AOP。

2.

有个有意思的地方在被CGLIB动态代理过的类再被Spring的AOP代理一次就会变成用JDK代理,因为CGLIB动态代理默认会继承一些接口。

正因为如此,这里会有个尴尬的地方,如果一个bean本身没有用接口,但是又被会被代理两次以上(第一次CGLIB,第二次JDK),那用@Autoware的地方就会抛错类似于:

Bean named 'xxxxxxx' is expected to be of type 'xxxxxxxx' but was actually of type 'com.sun.proxy.$Proxy21'
这时候解决办法有两个:

一:给bean加个接口

二:强制使用CGLIB : proxyTargetClass="true"


阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 吴晓波15亿交易失败 魔游游手机交易平台 8868手游交易平台 有内鬼终止交易 糖果交易平台app下载 二手房交易税费 糖果交易平台app 交易员底薪6000可信吗 房地产交易手续费 有内鬼终止交易锁屏 交易保罗分歧曝光 交易的英文单词 交易是什么意思 私下古董交易 艺术品交易网站 古玩古董交易 农行贵金属交易 古董交易公司 二手房交易代办 艺术品私下交易 二手奢侈品交易 经济适用房交易 通达信自动交易 古董青铜器交易 寻宝交易平台 贵金属交易系统 高古玉私下交易 碳排放权交易 模拟交易系统 贵金属交易公司 收藏品交易市场 收藏品交易中心 黄金交易公司 古瓷器鉴定交易 虚拟商品交易 收藏品私下交易 渤海交易平台 jiaoyimao 江西公共资源交易 滁州公共资源交易中心 古董古玩鉴定交易