欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Aop源码分析

程序员文章站 2022-12-15 07:55:57
最近看了SpringAop的源码实现 大概记录一下aop的源码流程 创建一个最简单的一个测试类 package com.zcg.learn.Test; import org.aopalliance.aop.Advice;import org.junit.Test;import org.springf ......

最近看了springaop的源码实现  大概记录一下aop的源码流程

创建一个最简单的一个测试类

package com.zcg.learn.test;

import org.aopalliance.aop.advice;
import org.junit.test;
import org.springframework.aop.aspectj.aspectjexpressionpointcutadvisor;
import org.springframework.aop.aspectj.annotation.aspectjproxyfactory;
import org.springframework.aop.framework.advised;
import org.springframework.aop.framework.proxyfactory;
import org.springframework.tests.aop.advice.countingafterreturningadvice;
import org.springframework.tests.aop.advice.countingbeforeadvice;

import com.zcg.learn.userservice;
import com.zcg.learn.userserviceimpl;

/**
* springaop源码分析测试类
* @author zcg
* 2018/3/1
*
*/
public class springaoptest {

/**
* 创建代理
*/
@test
public void createproxytest() {
object target = new userserviceimpl();
proxyfactory pf = new proxyfactory(target);
//countingbeforeadvice 前置通知计数器
countingbeforeadvice countingbeforeadvice = new countingbeforeadvice();
pf.addadvice(countingbeforeadvice);
userservice service = (userservice) pf.getproxy();
service.adduser();
}

/**
* 动态添加 移除通知
*/
@test
public void createproxytest2() {
object target = new userserviceimpl();
proxyfactory pf = new proxyfactory(target);
userservice service = (userservice) pf.getproxy();
advised advised = (advised) service;
countingbeforeadvice countingbeforeadvice = new countingbeforeadvice();
countingafterreturningadvice countingafterreturningadvice = new countingafterreturningadvice();
advised.addadvice(countingafterreturningadvice);
advised.addadvice(countingbeforeadvice);
service.adduser();
advised.removeadvice(countingafterreturningadvice);
service.adduser();
}

@test
public void createproxyaspectjbytest() {
object target = new userserviceimpl();
aspectjproxyfactory pf = new aspectjproxyfactory(target);
aspectjexpressionpointcutadvisor advisor = new aspectjexpressionpointcutadvisor();
advisor.setexpression("execution(* *.adduser(..))");
countingbeforeadvice counting = new countingbeforeadvice();
advisor.setadvice(counting);
pf.addadvisor(advisor);
userservice userservice = pf.getproxy();
userservice.adduser();
/**
* advice 通知拦截器
* advisor 通知加切入点适配器
*/


}

}

其中测试方式

@test
public void createproxytest() {
object target = new userserviceimpl();


proxyfactory pf = new proxyfactory(target);
//countingbeforeadvice 前置通知计数器
countingbeforeadvice countingbeforeadvice = new countingbeforeadvice();
pf.addadvice(countingbeforeadvice);
userservice service = (userservice) pf.getproxy();
service.adduser();
}

1.target 以构造参数的形式放入在proxyfactory中,实际上将该tartget放入在advisedsupport类中

Spring Aop源码分析

2.countingbeforeadvice 为spring aop自带的前置通知计数Spring Aop源码分析

3.1 userservice service = (userservice) pf.getproxy();从中获取代理类

proxyfactory类中 extends proxycreatorsupport

 

/*

* 代理生成工厂
*/
@suppresswarnings("serial")
public class proxyfactory extends proxycreatorsupport {

/**
* create a new proxy according to the settings in this factory.
* <p>can be called repeatedly. effect will vary if we've added
* or removed interfaces. can add and remove interceptors.
* <p>uses a default class loader: usually, the thread context class loader
* (if necessary for proxy creation).
* @return the proxy object
*/
public object getproxy() {
return createaopproxy().getproxy();
}

}

3.2 createaopproxy()方法是父类proxycreatorsupport里面的方法 

protected final synchronized aopproxy createaopproxy() {
if (!this.active) {
activate();
}

//得到aop代理工厂和在当前代理工厂创建该代理类
return getaopproxyfactory().createaopproxy(this);
}

其中getaopproxyfactory().createaopproxy(this)在defaultaopproxyfa1ctory类中执行 具体代码如下

@suppresswarnings("serial")
public class defaultaopproxyfactory implements aopproxyfactory, serializable {

@override
public aopproxy createaopproxy(advisedsupport config) throws aopconfigexception {
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.");
}

//r如果目标类有接口或者是代理类,则走jdk的动态代理 否则走cglib的动态代理
if (targetclass.isinterface() || proxy.isproxyclass(targetclass)) {
return new jdkdynamicaopproxy(config);
}
return new objenesiscglibaopproxy(config);
}
else {
return new jdkdynamicaopproxy(config);
}
}

/**
* determine whether the supplied {@link advisedsupport} has only the
* {@link org.springframework.aop.springproxy} interface specified
* (or no proxy interfaces specified at all).
*/
private boolean hasnousersuppliedproxyinterfaces(advisedsupport config) {
class<?>[] ifcs = config.getproxiedinterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && springproxy.class.isassignablefrom(ifcs[0])));
}

}

3.3 jdkdynamicaopproxy类实现了invocationhandler 对invoke进行的重写 核心代码如下

final class jdkdynamicaopproxy implements aopproxy, invocationhandler, serializable {

@override
public object invoke(object proxy, method method, object[] args) throws throwable {
methodinvocation invocation;
object oldproxy = null;
boolean setproxycontext = false;

targetsource targetsource = this.advised.targetsource;
class<?> targetclass = null;
object target = null;

try {
if (!this.equalsdefined && aoputils.isequalsmethod(method)) {
// the target does not implement the equals(object) method itself.
return equals(args[0]);
}
else if (!this.hashcodedefined && aoputils.ishashcodemethod(method)) {
// the target does not implement the hashcode() method itself.
return hashcode();
}
else if (method.getdeclaringclass() == decoratingproxy.class) {
// there is only getdecoratedclass() declared -> dispatch to proxy config.
return aopproxyutils.ultimatetargetclass(this.advised);
}
else if (!this.advised.opaque && method.getdeclaringclass().isinterface() &&
method.getdeclaringclass().isassignablefrom(advised.class)) {
// service invocations on proxyconfig with the proxy config...
return aoputils.invokejoinpointusingreflection(this.advised, method, args);
}

object retval;

if (this.advised.exposeproxy) {
// make invocation available if necessary.
oldproxy = aopcontext.setcurrentproxy(proxy);
setproxycontext = true;
}

// may be null. get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetsource.gettarget();
if (target != null) {
targetclass = target.getclass();
}

// get the interception chain for this method. 生成通知链条 当前对象和方式是否在拦截范围内
list<object> chain = this.advised.getinterceptorsanddynamicinterceptionadvice(method, targetclass);

// check whether we have any advice. if we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a methodinvocation.
//如果没有调用掉直接执行方式
if (chain.isempty()) {
// we can skip creating a methodinvocation: just invoke the target directly
// note that the final invoker must be an invokerinterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
object[] argstouse = aopproxyutils.adaptargumentsifnecessary(method, args);
retval = aoputils.invokejoinpointusingreflection(target, method, argstouse);
}
else {
// we need to create a method invocation...  

//初始化methodinvocation类
invocation = new reflectivemethodinvocation(proxy, target, method, args, targetclass, chain);
// proceed to the joinpoint through the interceptor chain.

执行调用链的所有方法和本身方法
retval = invocation.proceed();
}

// massage return value if necessary.
class<?> returntype = method.getreturntype();
if (retval != null && retval == target &&
returntype != object.class && returntype.isinstance(proxy) &&
!rawtargetaccess.class.isassignablefrom(method.getdeclaringclass())) {
// special case: it returned "this" and the return type of the method
// is type-compatible. note that we can't help if the target sets
// a reference to itself in another returned object.
retval = proxy;
}
else if (retval == null && returntype != void.type && returntype.isprimitive()) {
throw new aopinvocationexception(
"null return value from advice does not match primitive return type for: " + method);
}
return retval;
}
finally {
if (target != null && !targetsource.isstatic()) {
// must have come from targetsource.
targetsource.releasetarget(target);
}
if (setproxycontext) {
// restore old proxy.
aopcontext.setcurrentproxy(oldproxy);
}
}
}

 

}

其中的 advisedsupport类的this.advised.getinterceptorsanddynamicinterceptionadvice(method, targetclass)方法主要得到代理的所有拦截器方法

核心代码如下

public list<object> getinterceptorsanddynamicinterceptionadvice(method method, class<?> targetclass) {
methodcachekey cachekey = new methodcachekey(method);
list<object> cached = this.methodcache.get(cachekey);
if (cached == null) {
cached = this.advisorchainfactory.getinterceptorsanddynamicinterceptionadvice(
this, method, targetclass);
this.methodcache.put(cachekey, cached);
}
return cached;
}

getinterceptorsanddynamicinterceptionadvice方法核心代码如下:

public class defaultadvisorchainfactory implements advisorchainfactory, serializable {

@override
public list<object> getinterceptorsanddynamicinterceptionadvice(
advised config, method method, class<?> targetclass) {

// this is somewhat tricky... we have to process introductions first,
// but we need to preserve order in the ultimate list.
list<object> interceptorlist = new arraylist<object>(config.getadvisors().length);
class<?> actualclass = (targetclass != null ? targetclass : method.getdeclaringclass());
boolean hasintroductions = hasmatchingintroductions(config, actualclass);
advisoradapterregistry registry = globaladvisoradapterregistry.getinstance();

for (advisor advisor : config.getadvisors()) {
if (advisor instanceof pointcutadvisor) {
// add it conditionally.
pointcutadvisor pointcutadvisor = (pointcutadvisor) advisor;
if (config.isprefiltered() || pointcutadvisor.getpointcut().getclassfilter().matches(actualclass)) {
methodinterceptor[] interceptors = registry.getinterceptors(advisor);
methodmatcher mm = pointcutadvisor.getpointcut().getmethodmatcher();
if (methodmatchers.matches(mm, method, actualclass, hasintroductions)) {
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));
}
}
}
}
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;
}

}

 

3.4 invocation.proceed()核心代码如下

public class reflectivemethodinvocation implements proxymethodinvocation, cloneable{

@override
public object proceed() throws throwable {
// we start with an index of -1 and increment early.
if (this.currentinterceptorindex == this.interceptorsanddynamicmethodmatchers.size() - 1) {
return invokejoinpoint();
}

object interceptororinterceptionadvice =
this.interceptorsanddynamicmethodmatchers.get(++this.currentinterceptorindex);
if (interceptororinterceptionadvice instanceof interceptoranddynamicmethodmatcher) {
// evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.

//执行所有调用链的所有方法
interceptoranddynamicmethodmatcher dm =
(interceptoranddynamicmethodmatcher) interceptororinterceptionadvice;
if (dm.methodmatcher.matches(this.method, this.targetclass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// dynamic matching failed.
// skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// it's an interceptor, so we just invoke it: the pointcut will have
// been evaluated statically before this object was constructed.
return ((methodinterceptor) interceptororinterceptionadvice).invoke(this);
}
}

}

其中前置拦截器方法如下

@suppresswarnings("serial")
public class methodbeforeadviceinterceptor implements methodinterceptor, serializable {

private methodbeforeadvice advice;


/**
* create a new methodbeforeadviceinterceptor for the given advice.
* @param advice the methodbeforeadvice to wrap
*/
public methodbeforeadviceinterceptor(methodbeforeadvice advice) {
assert.notnull(advice, "advice must not be null");
this.advice = advice;
}

//重写invoke方法

@override
public object invoke(methodinvocation mi) throws throwable {
this.advice.before(mi.getmethod(), mi.getarguments(), mi.getthis() );
return mi.proceed();
}

}

后置通知拦截器方法

@suppresswarnings("serial")
public class afterreturningadviceinterceptor implements methodinterceptor, afteradvice, serializable {

private final afterreturningadvice advice;


/**
* create a new afterreturningadviceinterceptor for the given advice.
* @param advice the afterreturningadvice to wrap
*/
public afterreturningadviceinterceptor(afterreturningadvice advice) {
assert.notnull(advice, "advice must not be null");
this.advice = advice;
}

@override
public object invoke(methodinvocation mi) throws throwable {
object retval = mi.proceed();
this.advice.afterreturning(retval, mi.getmethod(), mi.getarguments(), mi.getthis());
return retval;
}

}

流程大概如此  可能有点模糊,如果想继续学习加我qq:1051980588 一起探讨和看其他相关的源码解析视频