aop 實(shí)現(xiàn)有兩種方式
- ProxyFactoryBean方式: 這種方式是通過配置實(shí)現(xiàn)
- ProxyFactory方式:這種方式是通過編程實(shí)現(xiàn)
這里說 ProxyFactoryBean ,先上一張ProxyFactoryBean 的關(guān)系圖,后面能用到。
示例代碼:
/**
代理接口,如果不是接口使用CGLIB代理
/
public interface ProxyInterface {
void m();
void t();
}
/*-
目標(biāo)對(duì)象,接口的實(shí)現(xiàn)類
*/
public class Target implements ProxyInterface {
@Override
public void m() {
System.out.println("m");
}@Override
public void t() {
System.out.println("t");
}
}
/**
- 通知器
/
public class BeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("BeforeAdvice.....");
}
}
/* - 通知器
*/
public class AfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("AfterAdvice.....");
}
}
定義一個(gè)接口ProxyInterface, 實(shí)現(xiàn)類為 Target,聲明了兩個(gè)advice,用來增強(qiáng)Target 方法。配置文件如下(advice 配置的順序就是調(diào)用的順序):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- 目標(biāo)類 -->
<bean id="target" class="com.masz.springtest.aop.proxy.Target"/>
<!-- advice -->
<bean id="beforeAdvice" class="com.masz.springtest.aop.proxy.BeforeAdvice"/>
<bean id="afterAdvice" class="com.masz.springtest.aop.proxy.AfterAdvice"/>
<!-- 增強(qiáng)代理對(duì)象,ProxyFactoryBean 是一個(gè)FactoryBean , getBean() 時(shí)會(huì)調(diào)用它的getObject() 方法 -->
<bean id="targetProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 代理接口,如果沒有接口使用CGLIB生成代理類-->
<property name="proxyInterfaces">
<list>
<value>com.masz.springtest.aop.proxy.ProxyInterface</value>
</list>
</property>
<property name="singleton" value="true"/> <!-- 是否是單例 -->
<property name="target" ref="target"/> <!-- 指定增強(qiáng)目標(biāo)bean -->
<!-- 攔截器名稱 -->
<property name="interceptorNames">
<list>
<value>beforeAdvice</value>
<value>afterAdvice</value>
</list>
</property>
</bean>
</beans>
測(cè)試:
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(AopTest.class, args);
//直接獲取目標(biāo)類
Target t = applicationContext.getBean(Target.class);
t.m();
//獲取目標(biāo)的代理。 關(guān)鍵的是:ProxyFactoryBean 是一個(gè)FactoryBean
ProxyInterface proxy = (ProxyInterface)applicationContext.getBean("targetProxy");
proxy.m();
System.exit(0);
}
運(yùn)行結(jié)果:
m
BeforeAdvice.....
m
AfterAdvice.....
第一個(gè)方法沒有被增強(qiáng),第二個(gè)方法被增強(qiáng)了。
源碼分析:
從代碼中可以看到,通過applicationContext.getBean()獲取ProxyFactoryBean, ProxyFactoryBean 是一個(gè)FactoryBean 所以getObject() 方法就是獲取代理對(duì)象的入口方法。
ProxyFactoryBean.getObject() 源碼:
@Override
@Nullable
public Object getObject() throws BeansException {
//初始化advisor 鏈
initializeAdvisorChain();
//對(duì)singleton 和 prototype 類型區(qū)分,生成相應(yīng)的proxy
if (isSingleton()) {
//是singleton,調(diào)用此方法生成代理對(duì)象
return getSingletonInstance();
}
else {
if (this.targetName == null) {
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
//不是singleton,創(chuàng)建一個(gè)Prototype 的實(shí)例的代理對(duì)象
return newPrototypeInstance();
}
}
initializeAdvisorChain() 初始化 advisor chain:
/**
- 創(chuàng)建advisor 鏈。
- advisor 信息從BeanFactory 來的,每當(dāng)創(chuàng)建一個(gè)新的prototype實(shí)例被創(chuàng)建時(shí),BeanFactory 就會(huì)被刷新。
- 攔截器通過factory api 以編程的方式被添加,而且不受advisor改變的影響。
過程:
這個(gè)初始化advisor 鏈,是應(yīng)用第一次通過 ProxyFactoryBean 獲取代理對(duì)象時(shí)觸發(fā)的,
advisor 鏈初始化完成之后,會(huì)讀取配置中所有的通知器,這個(gè)讀取比較簡(jiǎn)單就是調(diào)用容器的getBean()方法;
然后把獲取的advice 加入到 advisor 鏈中,這個(gè)過程是addAdvisorOnChainCreation() 方法實(shí)現(xiàn)
*/
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
//這個(gè)是個(gè)標(biāo)識(shí)位,標(biāo)記通知器鏈?zhǔn)欠褚呀?jīng)初始化過了,如果已經(jīng)初始化完了就直接返回。
if (this.advisorChainInitialized) {
return;
}
//配置的advice 不能是空的,如果沒有配置advice就不用增強(qiáng)了。
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
//所有的bean 都是BeanFactory 管理的,所以BeanFactory不能是空
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
}
// Globals can't be last unless we specified a targetSource using the property...
if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
throw new AopConfigException("Target required after globals");
}
//遍歷所有的advice 名稱配置,獲取advice bean 并且添加到 advisor 鏈
for (String name : this.interceptorNames) {
if (logger.isTraceEnabled()) {
logger.trace("Configuring advisor or advice '" + name + "'");
}
//interceptor name 是 * 結(jié)尾的
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with a ListableBeanFactory");
}
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
else {
// If we get here, we need to add a named interceptor.
// We must check if it's a singleton or prototype.
//程序運(yùn)行到這里就要檢查添加的 interceptor 是 singleton 還是 prototype 類型。
Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) {
// Add the real Advisor/Advice to the chain.
//單例的 advice,就從beanFactory 中g(shù)et bean 了。
advice = this.beanFactory.getBean(name);
}
else {
// It's a prototype Advice or Advisor: replace with a prototype.
// Avoid unnecessary creation of prototype bean just for advisor chain initialization.
//prototype advice,要?jiǎng)?chuàng)建一個(gè)新的advice
advice = new PrototypePlaceholderAdvisor(name);
}
//添加advice 到 advisor chain
addAdvisorOnChainCreation(advice, name);
}
}
}
this.advisorChainInitialized = true;
}
上面方法中的 addAdvisorOnChainCreation() 方法:
把配置 advice 封裝成一個(gè) DefaultPointcutAdvisor 對(duì)象,包含了PointCut(默認(rèn)是Pointcut.TRUE) 和 advice。
然后把封裝成的 advisor 放到 advisors 集合中,這個(gè)過程是在 類AdvisedSupport 中實(shí)現(xiàn)的,ProxyFactoryBean 是這個(gè)類的子類,看上圖。
getSingletonInstance() 方法, 生成 singleton 代理對(duì)象。
/**
- Return the singleton instance of this class's proxy object,
- lazily creating it if it hasn't been created already.
- @return the shared singleton proxy
返回一個(gè)單例的代理對(duì)象,如果沒有創(chuàng)建則會(huì)進(jìn)行懶加載。
過程:首先讀取ProxyFactoryBean 的配置,為生成代理對(duì)象做好準(zhǔn)備,如:代理接口,目錄對(duì)象等。
再通過AopProxy 生成代理對(duì)象。
*/
private synchronized Object getSingletonInstance() {
//如果已經(jīng)創(chuàng)建了,就直接返回
if (this.singletonInstance == null) {
this.targetSource = freshTargetSource();
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
// Rely on AOP infrastructure to tell us what interfaces to proxy.
//根據(jù)AOP 框架來判斷需要代理的接口
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
//設(shè)置代理對(duì)象的接口
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
// Initialize the shared singleton instance.
super.setFrozen(this.freezeProxy);
//getProxy()方法,通過createAopProxy() 方法返回的AopProxy 得到代理對(duì)象。
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
/**
- getProxy() 方法出現(xiàn)了AopProxy 接口對(duì)象。
*/
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}
上面代碼中 createAopProxy() 返回的是一個(gè)AopProxy對(duì)象,這個(gè)對(duì)象有兩個(gè)實(shí)現(xiàn)類:JdkDynamicAopProxy,CglibAopProxy,看到名字就很清楚了分別對(duì)應(yīng)生成代理類不同的實(shí)現(xiàn)方式。getProxy() 方法調(diào)用AopProxy 類的getProxy() 方法返回代理對(duì)象。
Spring 使用AopProxy 接口對(duì)象把AOP代理的實(shí)現(xiàn)和框架其它部分區(qū)分開,體現(xiàn)面向接口編程。
createAopProxy() 方法是在ProxyFactoryBean 父類 ProxyCreatorSupport 中實(shí)現(xiàn)的,ProxyCreatorSupport 中又調(diào)用了AopProxyFactory 默認(rèn)實(shí)現(xiàn) DefaultAopProxyFactory.createAopProxy() 方法生成AopProxy 代理對(duì)象。
/**
- Subclasses should call this to get a new AOP proxy. They should <b>not</b>
- create an AOP proxy with {@code this} as an argument.
子類調(diào)用這個(gè)方法生成 AOP proxy。
在 AdvisedProxy 子類 ProxyFactoryBean 中通過 AopProxyFactory 來生成代理類,AdvisedProxy 封裝了所有的生成代理對(duì)象信息,如:實(shí)現(xiàn)接口,目錄類等。
AopProxyFactory 使用的是 DefaultAopProxyFactory,這個(gè)對(duì)象在 ProxyFactoryBean 父類 ProxyCreatorSupport 中被創(chuàng)建。
createAopProxy() 方法參數(shù)就是 AdvisedProxy 類型,這里傳的是this,就是 ProxyFactoryBean,ProxyFactoryBean也是AdvisedProxy子類(可以查看上面的類關(guān)系圖)。
*/
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
//這里是調(diào)用 AopProxyFactory 默認(rèn)實(shí)現(xiàn) DefaultAopProxyFactory.createAopProxy() 方法生成AopProxy 代理對(duì)象。
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
//目錄對(duì)象的class
Class<?> targetClass = config.getTargetClass();
//沒有目標(biāo)對(duì)象拋出異常
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
//targetClass 是接口類,使用 JDK來生成 Proxy
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//如果不是接口類,使用CGLIB 生成代理對(duì)象
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
JdkDynamicAopProxy 源碼分析:
JdkDynamicAopProxy 本身實(shí)現(xiàn)了 InvocationHandler 接口和 AopProxy 接口所以 JdkDynamicAopProxy實(shí)現(xiàn)的InvocationHandler.invoker() 方法就是Proxy 對(duì)象回調(diào)的方法。
實(shí)現(xiàn)的AopProxy.getProxy() 方法就是通過JDK動(dòng)態(tài)代理生成的代理對(duì)象,傳遞的InvocationHandler 對(duì)象就是 JdkDynamicAopProxy 自身。
這就是動(dòng)態(tài)代理了,切面的實(shí)惠就是在 invoke() 方法中體現(xiàn)的。后面再分析如何實(shí)現(xiàn)AOP。
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
//獲取目標(biāo)類上的接口并且判斷是否需要添加SpringProxy Advised DecoratingProxy(spring4.3 新增) 接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
//判斷的目標(biāo)對(duì)象實(shí)現(xiàn)的接口是否定義了equals或hashCode方法,
//在invoke() 方法調(diào)用的時(shí)候會(huì)對(duì) equals 和 equals 做特殊的處理,參考后面
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//返回動(dòng)態(tài)代理對(duì)象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
總結(jié):
通過AopProxy 對(duì)象封裝target 目標(biāo)對(duì)象之后,ProxyFactoryBean方法得到的對(duì)象已經(jīng)是一個(gè)AopProxy代理對(duì)象了,在ProxyFactoryBean 中配置的target目標(biāo)對(duì)象不會(huì)讓應(yīng)用直接調(diào)用其方法的實(shí)現(xiàn),對(duì)target目標(biāo)對(duì)象的方法調(diào)用會(huì)被AopProxy代理對(duì)象攔截,對(duì)于不同的AopProxy代理對(duì)象生成方式,會(huì)使用不同的攔截回調(diào)入口。對(duì)于 JDK的AopProxy代理對(duì)象,使用的是InvocationHander的invoker 回調(diào)入口。對(duì)于CGLIB的AopProxy代理對(duì)象,使用的是設(shè)置好的callbak 回調(diào),在這里callback回調(diào)中,對(duì)于AOP的實(shí)現(xiàn)是通過DynamicAdvisedInterceptor 來完成的,DynamicAdvisedInterceptor 的回調(diào)入口是 intercept 方法(后面再分析CGLIB)。
這里只是AopProxy 代理對(duì)象的生成,通過這個(gè)過程把代理對(duì)象和攔截器待調(diào)用的部分都準(zhǔn)備好。下面就分析AOP運(yùn)行過程中對(duì)這些攔截器和代理對(duì)象的調(diào)用過程。
AOP 攔截器調(diào)用實(shí)現(xiàn):
如果是JDK實(shí)現(xiàn)的代理對(duì)象就會(huì)通過InvocationHandler 來完成攔截器回調(diào),如果是CGLIB 就通過DynamicAdvisedInterceptor 來完成回調(diào)。
JdkDynamicAopProxy 的 invoke 攔截:
在 JdkDynamicAopProxy.getProxy() 方法中,調(diào)用的的JDK動(dòng)態(tài)代理生成代理類,JdkDynamicAopProxy 自身實(shí)現(xiàn)了InvocationHandler 接口,那么代理對(duì)象調(diào)用目標(biāo)對(duì)象方法時(shí)會(huì)被invoke() 方法攔截
JdkDynamicAopProxy.invoke() 源碼:
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
//從advised中獲取目標(biāo)對(duì)象
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
//目標(biāo)對(duì)象沒有重寫Object 的equals() 方法
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
//目標(biāo)對(duì)象沒有重寫 Object的 hashCode() 方法
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
// 如果方法是在DecoratingProxy聲明的,
// DecoratingProxy 只有g(shù)etDecoratedClass() 一個(gè)方法,所有在這里直接調(diào)用
// 返回代理類的終極目標(biāo)類。
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...
//Spring AOP不會(huì)增強(qiáng)直接實(shí)現(xiàn)Advised接口的目標(biāo)對(duì)象。
//這里直接通過反射調(diào)用。
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
//返回值
Object retVal;
//是否暴露代理對(duì)象,如果暴露意味著在線程內(nèi)共享代理對(duì)象,在線程內(nèi)可通過AopContext 獲取代理對(duì)象。就是通過ThreadLocal 實(shí)現(xiàn)的。
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 目標(biāo)對(duì)象
target = targetSource.getTarget();
// 目標(biāo)對(duì)象類
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
//獲取目標(biāo)方法的攔截器鏈
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.
// 檢查是否的攔截器,如果沒有那么就直接通過反射調(diào)用目標(biāo)方法,MethodInvocation就不用創(chuàng)建了
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.
//如果沒有攔截器,就不用創(chuàng)建 MethodInvocation,直接在目標(biāo)對(duì)象上反射調(diào)用方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
//創(chuàng)建一個(gè) ReflectiveMethodInvocation,這個(gè)類是實(shí)現(xiàn)AOP的功能的封裝
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();
// retVal不空 并且和目標(biāo)方法的返回類型一致,就返回。
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);
}
}
}
注:
invoke 方法中獲取調(diào)用攔截器鏈方法
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
這個(gè)方法把 PintcutAdvice 封裝成 MethodInterceptor。MethodInterceptor 有兩個(gè)實(shí)現(xiàn)類具體的為 MethodBeforeAdviceInterceptor 和 AfterReturningAdviceInterceptor
MethodInterceptor.invoke() 方法,將的 ReflectiveMethodInvocation.proceed() 中被調(diào)用,MethodInterceptor.invoke()方法的參數(shù)就是 MethodInvocation 類型,而 ReflectiveMethodInvocation 是 MethodInvocation 的子類,在invoke() 方法中又回調(diào)了 MethodInvocation.proceed()方法,這樣就又回調(diào)回去了,當(dāng) "this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1" 時(shí)也就是攔截器調(diào)用完了,就通過反射調(diào)用目標(biāo)方法。
ReflectiveMethodInvocation 和 MethodInterceptor 就是實(shí)現(xiàn)Spring AOP 的核心所在。具體查看MethodBeforeAdviceInterceptor 和 AfterReturningAdviceInterceptor 這個(gè)兩個(gè)實(shí)現(xiàn)源碼就
JdkDynamicAopProxy AOP功能,就是通過 ReflectiveMethodInvocation 類實(shí)現(xiàn)的
ReflectiveMethodInvocation.proceed() 源碼分析:
//這個(gè)方法是遞歸方法,當(dāng)所有攔截器都執(zhí)行完畢了,就通過反射調(diào)用目標(biāo)方法返回。
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//使用 currentInterceptorIndex 記錄攔截器調(diào)用的下標(biāo),當(dāng)所有攔截器都調(diào)用完畢后,通過反射調(diào)用目標(biāo)方法。
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//反射調(diào)用目標(biāo)方法
return invokeJoinpoint();
}
//從攔截器鏈中獲取一個(gè)攔截器,下標(biāo)是 ++this.currentInterceptorIndex
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.
//動(dòng)態(tài)匹配
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
//如果方法和定義的切點(diǎn)匹配成功就執(zhí)行
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.
//執(zhí)行到這里就是一個(gè) MethodInterceptor , 則直接調(diào)用
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
在示例代碼中配置的是通知器,不是切面,如果配置的是切面就要走動(dòng)態(tài)匹配了(動(dòng)態(tài)匹配就是走jdk的正則匹配 MethodMatcher ,不擴(kuò)展了)。
總結(jié):每個(gè) MethodInterceptor 對(duì)應(yīng)的都有實(shí)現(xiàn)AfterReturningAdviceInterceptor, MethodBeforeAdviceInterceptor, ThrowsAdviceInterceptor。如 MethodBeforeAdviceInterceptor
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
則是調(diào)用完invoke() 方法后,就又調(diào)用了MethodInvocation.proceed() 方法,又回到了上一步方法中,這樣一直循環(huán)調(diào)用,直到所有的interceptor 調(diào)用完畢。
總結(jié):ProxyFactoryBean 通過jdk動(dòng)態(tài)代理機(jī)制生成代理對(duì)象,當(dāng)調(diào)用代理對(duì)象方法時(shí),會(huì)被invoke() 方法攔截。在invoke() 方法中又獲取了此方法的攔截器,通過對(duì)攔截器的調(diào)用實(shí)現(xiàn)了spring aop功能。CGLIB的實(shí)現(xiàn)只是生成代理對(duì)象的方式不同,這就讓攔截器的入口有了變化。攔截器的生成和調(diào)用機(jī)制是一樣的??吹诙?。
注:這里通過 initializeAdvisorChain(); 把a(bǔ)dvice 封裝成了advisor,又如何把a(bǔ)dvisor 封裝成具體的interceptor 呢? 看后續(xù)...
————————————————
版權(quán)聲明:本文為CSDN博主「Jamin_Ma」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/convict_eva/article/details/81084833