spring AOP 源码解析 及其实现原理

1 篇文章 0 订阅
1 篇文章 0 订阅

AOP的实现总体上是代理模式的应用


我们以ProxyFactoryBean生成代理类为例。

首先ProxyFactoryBean调用initalizaAdvisorChain()来进行通知器链的构建。之后调用DefalutAopProxyFactory的createAopProxy()方法生成一个代理类,在createAopProxyFactory方法中,有两种生成代理类的方式。

public AopProxy createAopProxy(AdviseSupport config) throws AopConfigException{
...
if(tagetClass.isInterface){
return new JdbcDynamicAopProxy(config);}
return CglibProxyFactory.createCglibProxy(config);
}

 
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">当被代理的对象是实现相关接口的类时,通过JDK的动态代理机制来生成代理类,否则通过CGLIB来生成代理类。</span></span>

在JDK的动态代理机制中,有一个invocationHandler接口,定义了invoke方法。

/*

proxy 被代理对象

method 代理的方法

args 参数

public Object invoke(Object proxy,Method method,Object[] args);


主要通过Proxy.newProxyInstance方法生成代理类,该方法需要三个参数:类加载器,代理接口,实现了InvocationHandler接口的对象。

又因为JdbcDynamicAopProxy本身实现了InvocationHandler接口,故可将this作为newProxyInstance的参数。这样在生成一个代理类后,当被代理对象的方法被执行时,会转化为执行代理类的方法,而JdbcDynamicAopProxy的invoke方法将作为代理类的回调函数而执行,所以最后关键是invoke方法的实现确定了被代理对象的相关方法的具体行为。下面我们分析invoke方法的实现原理:

在invoke方法中,首先根据通知器链生成拦截器链,在将拦截器链,被代理对象等参数封装生成一个ReflectiveMethodInvocation对象,最后调用该对象的proceed方法。


我们先分析拦截器链的构造过程,即单个拦截器的构造过程。

spring Aop中使用适配器模式来实现了这一功能,及将不同的Advice生成相应的拦截器并定义他们的统一方法。

以MethodBeforeAdvice为例,通过MethodBeforeAdviceAdapter生成MethodBeforeAdviceInterceptor拦截器对象,而所有的拦截器对象都实现了MethodIntecptor的invoke方法,下面举MethodBeforeAdviceInterceptor的invoke方法实现为例:

public Object invoke(MethodInvocation mi){

this.advice.before(mi.getMethod(),mi.getArguments(),mi.getThis());

return mi.proceed();

}

在执行被代理对象的真实方法前执行前置Advice的before方法,实现了对方法执行前的行为增强。

其他类型advice实现原理和这差不多。


这样我们就构造了一个拦截器链。现在我们再回到ReflectiveMethodInvocation对象的proceed方法中,分析该方法的实现原理:

public Object proceed(){

//到达拦截器链末尾是通过反射机制执行被代理对象的实现方法

if(this.currentInterceptorIndex==this...)

return invokeJoinpoint();

Object inteceptorOrInteceptionAdvice=this.interceptorAndDynamaticMethodMatchers.get(++this.currentInterceptorIndex);

if(inteceptorOrInteceptionAdvice instanceof InterceptorAndDynamaticMethodMatcher){

InterceptorAndDynamaticMethodMatcher dm=(InterceptorAndDynamaticMethodMatcher)inteceptorOrInteceptionAdvice;

if(dm.methodMatcher.matchs(this.method,this.targetClass,this.arguments)){

return dm.interceptor.invoke(this);

}else{

proceed();

}

}

else{

return inteceptorOrInteceptionAdvice.invoke(this);

}

}


如代码所示,在proceed方法中,先进行判断,如果已经运行到拦截器链的末尾,泽直接调用目标对象的实现方法(反射机制)。否则,沿着拦截器继续执行,

得到下一个拦截器,如果该拦截器适用于该场合,则启动该拦截器的invoke方法进行切面增强。在该过程结束后,会迭代调用proceed方法,直到拦截器链的

拦截器都完成以上的拦截过程为止。


这就是通过JDK的动态代理机制生成代理类的实现原理。

而对于CGLIB的生成机制中,是通过字节码层面的技术生成被代理类的一个子类并重写相应方法实现的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值