当前位置: 移动技术网 > IT编程>开发语言>Java > Spring Aop源码分析

Spring Aop源码分析

2019年03月05日  | 移动技术网IT编程  | 我要评论

最近看了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类中

2.countingbeforeadvice 为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 一起探讨和看其他相关的源码解析视频  

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网