从入口开始分析
ProxyFactoryBean继承自FactoryBean,分析其源码首先联想到从getObject入手,代码如下。
@Override
public Object getObject() throws BeansException {
initializeAdvisorChain();
if (isSingleton()) {
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.");
}
return newPrototypeInstance();
}
}
调用initializeAdvisorChain初始化advisor链条,然后根据是否为单例创建代理对象。
AOP执行过程中涉及到的重要节点
-
initializeAdvisorChain
通过读取interceptorNames
将BeanFactory
工厂内对应的Advice
,Advisor
,MethodInterceptor
通过AdvisorAdapterRegistry.wrap
(Advice需要有对应的AdvisorAdapter的支持才可以转换)转换为Advisor
然后加载到执行链条中。 -
AopProxyFactory
根据AdvisedSupport
(ProxyFactorybean
的父类)的配置生成不同的AopProxy
,JdkDynamicAopProxy
或者ObjenesisCglibAopProxy
。生成AopProxy
时已将AdvisedSupport
注入到AopProxy
中。 -
AopProxy
生成代理对象, 当代理对象调用具体方法时,会通过AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice
将之前注入到advisorChain
中的advisors
转换为MethodInterceptor
和InterceptorAndDynamicMethodMatcher
集合。然后根据集合迭代执行Interceptor
的invoke
,最终反射执行真正对象的方法调用。
AdvisorAdapter的承接作用
DefaultAdvisorAdapterRegistry.java
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List adapters = new ArrayList(3);
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List interceptors = new ArrayList(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
AdvisorAdapter.java
public interface AdvisorAdapter {
boolean supportsAdvice(Advice advice);
MethodInterceptor getInterceptor(Advisor advisor);
}
前面讲到代理对象执行方法时,无论是注册Advice
还是Advisor
都是将其转换为MethodInterceptor
和InterceptorAndDynamicMethodMatcher
并调用
Object invoke(MethodInvocation invocation) throws Throwable;
来执行拦截逻辑。所以这中间需要一个AdvisorAdapter
将Advice
和Advisor
来转换为MethodInterceptor
。Spring在这里使用了和HandlerMapping
一样的设计原则。提供一个supportAdvice
方式用于判断是否支持传入进来的Advice
,如果支持,那么当传入一个Advisor
时,通过获取其Advice
,并通过一个MethodInterceptor
的子类封装起来返回。
同样的看到AdvisorAdapterRegistry.wrap
源码可以发现逻辑为对于Advice类型但非MethodInterceptor
类型的adviseObject会循环遍历内部的adapters
,一个个判断supportsAdvice
,如果支持才会将Advice
封装为Advisor
返回。后续在拿到Advisor
并传入AdvisorAdapter.getInterceptor()
时才可以取得到对应的MethodInterceptor
。下面贴出MethodBeforeAdviceAdapter
的源码来看看。
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
可以看到本质还是调用MethodBeforeAdvice.before来做拦截只不过包装了一下。
JdkDynamicAopProxy如何执行
JdkDynamicAopProxy实现了InvocationHandler接口,所以通过Proxy.newInstance出来的对象方法调用最终会回调JdkDynamicAopProxy.invoke。下面是invoke代码片段
List
getInterceptorsAndDynamicInterceptionAdvice就是上文讲的获取MethodInterceptor和InterceptorAndDynamicMethodMatcher的集合。最终传入ReflectiveMethodInvocation中然后进行proceed。下面我们看看ReflectiveMethodInvocation.proceed内部是如何处理的。
@Override
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
return proceed();
}
}
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
内部记录currentInterceptorIndex
索引,如果索引还未超过Interceptors
集合的最大索引,代表仍然有interceptor
需要调用,此时++currentInterceptorIndex
并且获取对应的Interceptor
。如果是InterceptorAndDynamicMethodMatcher
代表是运行时继续匹配再次执行match,匹配通过后执行拦截逻辑,如果是普通的MethodInterceptor
直接调用invoke
。
在这里由于invoke
传入的是ReflectiveMethodInvocation
再结合我们在对应的MethodInterceptor.invoke(MethodInvocation invocation)
内部调用invocation.proceed
,所以这里会形成一个递归调用。所以当所有的Interceptor
都调用过后,调用invokeJoinpoint()通过反射调用被代理对象的实际方法。
到此一条完整的AOP执行逻辑已经结束,还有很多细节没有讲,但是没想好如何继续写出来,因为比较零碎,不好组织。有问题欢迎评论探讨