AbstractAutoProxyCreator

在AbstractAutoProxyCreator的wrapIfNecessary方法中,调用getAdvicesAndAdvisorsForBean方法获取到所有的Advisor之后,就可以创建代理对象了,创建的具体过程在createProxy方法中:

  1. 创建代理工厂ProxyFactory
  2. 调用buildAdvisors构建Advisor,入参是getAdvicesAndAdvisorsForBean获取到的Advice和Advisor,里面又调用了AdvisorAdapterRegistry的wrap方法判断Advice是否是Advisor类型,这一步主要是对通知Advice进行校验,如果通知不是Advisor类型将其包装为Advisor
  3. 通过代理工厂ProxyFactory生成代理对象
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
/**
* 是否有必要生成代理对象
* @param bean
* @param beanName
* @param cacheKey
* @return
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
} // 获取Advices和Advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理,specificInterceptors就是获取到的Advices和Advisors
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
} /**
* 创建代理对象
*/
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 1.创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 2.构建Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 设置Advisor
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 3.生成代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
}

构建Advisor

AbstractAutoProxyCreator的buildAdvisors主要是对通知Advice进行校验,如果通知不是Advisor类型将其包装为Advisor,具体是通过AdvisorAdapterRegistry的wrap方法实现的:

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { // 调用GlobalAdvisorAdapterRegistry的getInstance获取AdvisorAdapterRegistry实例
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance(); /**
* 构建Advisors,specificInterceptors是上一步获取到的Advice和Advisor
*/
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
Advisor[] commonInterceptors = resolveInterceptorNames(); List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
// 将获取到的Advice和Advisor添加到拦截器中
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
// 创建Advisor集合
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
// 调用AdvisorAdapterRegistry的wrap方法将通知包装为Advisor进行增强,在DefaultAdvisorAdapterRegistry中实现
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
} }

AdvisorAdapterRegistry

在GlobalAdvisorAdapterRegistry中可以看到使用的是DefaultAdvisorAdapterRegistry:

public final class GlobalAdvisorAdapterRegistry {
/**
* 使用DefaultAdvisorAdapterRegistry
*/
private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry(); /**
* 返回AdvisorAdapterRegistry
*/
public static AdvisorAdapterRegistry getInstance() {
return instance;
}
}

DefaultAdvisorAdapterRegistry

DefaultAdvisorAdapterRegistry中的wrap方法主要逻辑如下:

  1. 如果当前的通知已经是Advisor类型直接返回即可
  2. 如果当前的通知不是Advice类型,抛出异常
  3. 将通知转为Advice,对通知进行判断
    • 如果通知是MethodInterceptor方法拦截器,将其包装为DefaultPointcutAdvisor
    • 如果不是MethodInterceptor,遍历Adapter适配器,找出支持当前通知的适配器,再将通知包装为DefaultPointcutAdvisor返回
  4. 非以上几种情况抛出异常
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
// 如果已经是Advisor,返回即可
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
// 如果不是Advice类型,抛出异常
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
// 转为Advice
Advice advice = (Advice) adviceObject;
// 如果是一个方法拦截器
if (advice instanceof MethodInterceptor) {
// 包装为DefaultPointcutAdvisor
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// 判断Advisor适配器是否支持当前的Advice
if (adapter.supportsAdvice(advice)) {
// 包装为DefaultPointcutAdvisor
return new DefaultPointcutAdvisor(advice);
}
}
// 抛出异常
throw new UnknownAdviceTypeException(advice);
}
}

生成代理对象

上一步中已经对所有的Advice进行了校验,转为了Advisor进行增强,接下来就可以生成代理对象了,具体实现在ProxyFactory的getProxy中:

  1. 调用createAopProxy获取AopProxy,AopProxy是一个接口,定义了getProxy获取代理对象的方法,它有两个实现类分别为CglibAopProxyJdkDynamicAopProxy

  1. 调用AopProxy的getProxy方法获取代理对象
public class ProxyFactory extends ProxyCreatorSupport {
/**
* 获取代理对象
*/
public Object getProxy(@Nullable ClassLoader classLoader) {
// 通过工厂创建AOP代理对象,createAopProxy方法在ProxyCreatorSupport中实现
return createAopProxy().getProxy(classLoader);
} }

createAopProxy创建AopProxy

createAopProxy的实现逻辑在ProxyFactory的父类ProxyCreatorSupport中实现,它使用了工厂模式生成代理对象:

  1. 调用getAopProxyFactory方法获取AopProxyFactory,在无参构造函数中可以看的默认使用的工厂是DefaultAopProxyFactory
  2. 调用AopProxyFactory的createAopProxy方法创建代理对象
// ProxyCreatorSupport
public class ProxyCreatorSupport extends AdvisedSupport { // AOP代理工厂
private AopProxyFactory aopProxyFactory; /**
* 无参构造函数
*/
public ProxyCreatorSupport() {
// 工厂的实现默认使用DefaultAopProxyFactory
this.aopProxyFactory = new DefaultAopProxyFactory();
} /**
* 带有AopProxyFactory参数的构造函数
*/
public ProxyCreatorSupport(AopProxyFactory aopProxyFactory) {
Assert.notNull(aopProxyFactory, "AopProxyFactory must not be null");
this.aopProxyFactory = aopProxyFactory;
} /**
* 创建AopProxy
*/
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 1.调用getAopProxyFactory获取AopProxy,2.调用AopProxy的createAopProxy创建代理对象
return getAopProxyFactory().createAopProxy(this);
} /**
* 返回AOP代理工厂
*/
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
}

DefaultAopProxyFactory

DefaultAopProxyFactory中创建AOP代理的逻辑如下:

  1. 获取目标对象的Class信息
  2. 对Class进行判断:
  • 如果是一个接口或者isProxyClass返回true使用JDK动态代理生成代理对象,isProxyClass方法在JDK的Proxy中实现,返回true的条件为目标类是java.lang.reflect.Proxy的子类并且缓存中包含目标类
  • 如果上一个条件不满足则使用CGLIB生成代理对象
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

    @Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 获取目标对象的Class信息
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.");
}
// 如果是一个接口
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则使用CGLIB生成代理对象
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
} // java.lang.reflect.Proxy
public class Proxy implements java.io.Serializable { public static boolean isProxyClass(Class<?> cl) {
// 是否是java.lang.reflect.Proxy的子类并且缓存中包含目标类
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}
}

到此AopProxy已经创建成功,接下来以JdkDynamicAopProxy为例查看getProxy获取代理对象过程。

getProxy获取代理对象

JdkDynamicAopProxy是通过JDK的动态代理实现代理创建的,可以看到它实现了InvocationHandler接口,关于JDK的动态代理实现原理可参考【JAVA】动态代理,这里我们需要关注getProxy和invoke方法:

  • getProxy:创建代理对象
  • invoke:当代理对象中引用的方法执行时会进入这个方法中
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

    @Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
} @Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 生成代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
} @Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 先省略 }
}

getProxy创建代理对象

可以看到是通过JDK中Proxy的newProxyInstance生成代理对象的:


final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { @Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 生成代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
}

invoke方法

当调用AOP中需要被通知拦截的方法时,会进入到invoke方法,比较核心的是getInterceptorsAndDynamicInterceptionAdvice获取拦截器链,如果为空直接通过反射执行目标方法即可,如果不为空,将方法包装为MethodInvocation,然后执行拦截器链

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

    /** AdvisedSupport */
private final AdvisedSupport advised; /**
* InvocationHandler中定义的invoke方法,当目标方法执行时会进入到这个方法中
* @param proxy 代理对象
* @param method 需要被执行的目标方法
* @param args
* @return
* @throws Throwable
*/
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource;
Object target = null; try {
// 如果是equals方法
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)) {
// 如果是hashCode方法
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// 如果方法所在类是DecoratingProxy类
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
} Object retVal;
// 是否需要暴露代理
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null); // 获取当前方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // 校验拦截器链是否为空
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 如果为空直接执行目标方法即可
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 创建MethodInvocation
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 执行拦截器链
retVal = invocation.proceed();
} // 获取方法返回值
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
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中实现,它主要用于将适用于当前方法的Advisor转为方法拦截器,首先它先从缓存中查询,如果未查询到,调用advisorChainFactory方法的getInterceptorsAndDynamicInterceptionAdvice进行获取,在DefaultAdvisorChainFactory中实现:

public class AdvisedSupport extends ProxyConfig implements Advised {
/** AdvisorChainFactory,默认使用DefaultAdvisorChainFactory*/
AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
/**
* 获取方法的拦截器链
*/
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
// 构建缓存KEY
MethodCacheKey cacheKey = new MethodCacheKey(method);
// 从缓存获取
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
// 如果未从缓存中获取到,调用getInterceptorsAndDynamicInterceptionAdvice获取方法的拦截器链
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
// 加入到缓存
this.methodCache.put(cacheKey, cached);
}
return cached;
}
}

DefaultAdvisorChainFactory

getInterceptorsAndDynamicInterceptionAdvice中先获取了所有的Advisor,然后遍历Advisor,对Advisor进行判断:

  1. 如果是PointcutAdvisor类型,将Advisor转为PointcutAdvisor,然后获取Pointcut切点的ClassFilter,通过matches方法判断当前方法所属的class是否匹配,如果匹配,则从切点中获取MethodMatcher方法匹配器,调用它的matches方法判断切点与当前方法是否匹配,如果也匹配,调用AdvisorAdapterRegistry的getInterceptors将Advisor转为方法拦截器

  2. 如果是引入通知IntroductionAdvisor,并且ClassFilter的matches与当前类匹配,调用AdvisorAdapterRegistry的getInterceptors将Advisor转为方法拦截器

  3. 非以上两种情况,调用AdvisorAdapterRegistry的getInterceptors将Advisor转为方法拦截器

可以看到以上三种情况,最后都是调用了AdvisorAdapterRegistry获取拦截器的,接下来就进入AdvisorAdapterRegistry中查看getInterceptors的具体实现。

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
/**
* 获取方法的拦截器链
*/
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) { // 获取AdvisorAdapterRegistry
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 获取Advisor
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
// 遍历Advisor
for (Advisor advisor : advisors) {
// 如果是PointcutAdvisor类型
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 调用matches方法判断与当前class是否匹配
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
// 获取方法匹配器MethodMatcher
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
// 如果是IntroductionAwareMethodMatcher
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
// 调用MethodMatcher的matches方法匹配
match = mm.matches(method, actualClass);
}
if (match) {
// 如果匹配,从registry中获取方法拦截器
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
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) {
// 将拦截器封装为InterceptorAndDynamicMethodMatcher
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
// 如果是引入通知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;
}
}

DefaultAdvisorAdapterRegistry

在DefaultAdvisorAdapterRegistry的构造函数中注册了三种AdvisorAdapter,使用了适配器模式将Advisor转换为方法拦截器MethodInterceptor,三种AdvisorAdapter分别为:

  • MethodBeforeAdviceAdapter:支持前置通知MethodBeforeAdvice
  • AfterReturningAdviceAdapter:支持返回通知AfterReturningAdvice
  • ThrowsAdviceAdapter:支持ThrowsAdvice

AspectJAfterThrowingAdvice、AspectJAroundAdvice和AspectJAfterAdvice本身已经实现了MethodInterceptor接口,所以不需要进行转换:

在getInterceptors方法中,对Advisor进行判断,如果本身已经是MethodInterceptor直接返回即可,否则遍历所有的AdvisorAdapter,找出支持当前Advisor的Adapter,然后将Advisor转为MethodInterceptor:

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {

    private final List<AdvisorAdapter> adapters = new ArrayList<>(3);

    /**
* 注册AdvisorAdapter
*/
public DefaultAdvisorAdapterRegistry() {
// 注册MethodBeforeAdviceAdapter
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
// 注册AfterReturningAdviceAdapter
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
// 注册ThrowsAdviceAdapter
registerAdvisorAdapter(new ThrowsAdviceAdapter());
} @Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
// 从Advisor中获取Advice
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 遍历Adapter
for (AdvisorAdapter adapter : this.adapters) {
// 判断是否支持当前的通知
if (adapter.supportsAdvice(advice)) {
// 通过Adapter获取拦截器
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
}

AdvisorAdapter有三个实现类,以MethodBeforeAdviceAdapter为例查看一下supportsAdvice和getInterceptor的实现:

  1. 在supportsAdvice方法中可以看到它支持的是MethodBeforeAdvice方法前置通知

  2. 在getInterceptor方法中,首先从Advisor中获取到了通知,然后将通知封装为MethodBeforeAdviceInterceptor返回

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

    @Override
public boolean supportsAdvice(Advice advice) {
// 是否是MethodBeforeAdvice类型
return (advice instanceof MethodBeforeAdvice);
} @Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
// 封装为MethodBeforeAdviceInterceptor
return new MethodBeforeAdviceInterceptor(advice);
} }

执行目标方法

回顾invoke方法中的主要逻辑,在获取到方法的拦截器之后,对拦截器是否为空进行了判断:

  • 如果为空,调用AopUtils的invokeJoinpointUsingReflection通过反射直接执行方法即可

  • 如果不为空创建MethodInvocation,具体实现类是ReflectiveMethodInvocation,然后调用proceed执行拦截器链


// 获取当前方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // 校验拦截器链是否为空
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 如果为空直接执行目标方法即可
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// 创建MethodInvocation,使用的是ReflectiveMethodInvocation类型
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 执行拦截器链
retVal = invocation.proceed();
}

invokeJoinpointUsingReflection

invokeJoinpointUsingReflection方法通过反射执行目标方法,在AopUtils中实现:

public abstract class AopUtils {

    @Nullable
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
throws Throwable { // 通过反射执行目标方法
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
} }

proceed方法执行拦截器链

因为拦截器可以有多个,所以proceed方法是一个递归调用的过程,currentInterceptorIndex记录了当前拦截器的下标:

  1. 判断currentInterceptorIndex是否与拦截器链的大小一致,如果一致说明已经走到了最后一个拦截器,调用invokeJoinpoint方法执行目标方法即可,可以看到调用了AopUtils的invokeJoinpointUsingReflection通过反射执行目标方法,如果不是最后一个拦截器进入第2步
  2. 对currentInterceptorIndex++,获取下一个拦截器,判断拦截器是否是InterceptorAndDynamicMethodMatcher类型,如果是获取methodMatcher对目标方法进行匹配:
    • 如果与目标方法匹配成功,执行拦截器的invoke方法
    • 如果与目标方法匹配不成功,递归调用proceed方法执行下一个拦截器
  3. 如果拦截器不是InterceptorAndDynamicMethodMatcher类型,直接调用方法拦截器MethodInterceptor的invoke执行拦截器即可

在执行MethodInterceptor方法拦截器的invoke方法时,传入的参数是this,指的是ReflectiveMethodInvocation对象本身,在拦截器方法执行后需要拿到这个对象调用proceed方法继续执行下一个拦截器,可以看到这里使用了责任链模式,对拦截器进行一个个的调用。

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
@Override
@Nullable
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) {
// 如果是InterceptorAndDynamicMethodMatcher
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
// 判断方法是否匹配
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// 如果方法不匹配,跳过当前拦截器执行下一个,递归调用
return proceed();
}
}
else {
// 转为MethodInterceptor执行拦截器,注意invoke传入的参数是this,指的是ReflectiveMethodInvocation对象本身,在拦截器的invoke方法中需要拿到这个对象调用proceed方法继续执行下一个拦截器
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
} /**
* 通过反射执行目标方法
*/
@Nullable
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
} }

MethodBeforeAdviceInterceptor

以前置通知为例,看一下MethodBeforeAdviceInterceptor拦截器中的invoke方法的执行逻辑:

  1. 前置通知是在目标方法执行之前执行的方法,所以先调用了invokeAdviceMethod执行了前置通知方法
  2. 调用MethodInvocation的proceed执行下一个拦截器链,在上一步中可以看到调用拦截器时传入的是this,this指向ReflectiveMethodInvocation,所以会继续执行到它的proceed方法,继续下一个拦截器的执行
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

    @Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 先执行通知方法,在AspectJMethodBeforeAdvice中实现
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 执行拦截器链,这里调用的是MethodInvocation的proceed方法,会再次进入到ReflectiveMethodInvocation的proceed方法中
return mi.proceed();
} }
// AspectJMethodBeforeAdvice
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {
@Override
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
// 执行通知方法
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}

AspectJAroundAdvice

再以环绕通知为例,看一下环绕通知的执行逻辑,AspectJAroundAdvice实现了MethodInterceptor接口,所以它本身就是一个拦截器,在invoke方法中它调用了invokeAdviceMethod执行通知方法,并将ReflectiveMethodInvocation转换为ProceedingJoinPoint,在环绕通知中通过ProceedingJoinPoint调用proceed方法执行下一个拦截器

public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {

    @Override
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
// mi是上一步中传入的ReflectiveMethodInvocation,这里将其转换为ProxyMethodInvocation
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
// 将ProxyMethodInvocation转为ProceedingJoinPoint
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
// 执行通知方法
return invokeAdviceMethod(pjp, jpm, null, null);
}
} @SuppressWarnings("serial")
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation, Serializable {
/**
* 执行通知方法
*/
protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable t) throws Throwable {
// 通过给定的参数执行通知方法
return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
/**
* 通过给定的参数执行通知方法
*/
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// 这里执行了通知方法,接下来会进入到定义的环绕通知方法中
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}

假设定义了如下的环绕通知,在环绕通知方法被执行时,会进入到logAroudAdvice方法中,可以看到先打印了方法执行前的日志,然后调用了ProceedingJoinPoint的proceed方法执行拦截器链,上一步可知ProceedingJoinPoint是MethodInvocation转换而来,所以又会进入到ReflectiveMethodInvocation的proceed方法执行下一个拦截器链,待所有的拦截器执行完毕后proceed方法也就结束,然后执行了printAfterLog打印方法执行后的日志:

    /**
* 通知Advice,这里使用了环绕通知
* @param joinPoint 连接点
* @return
* @throws Throwable
*/
@Around("logPoiontcut()") // 引用切点
public Object logAroudAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// 方法执行前的日志打印
printBeforeLog(joinPoint);
// 执行拦截器链
Object returnValue = joinPoint.proceed();
// 方法执行后的日志打印
printAfterLog(returnValue);
return returnValue;
}

总结

方法拦截器链的执行流程图

AOP总结

参考

【猫吻鱼】Spring源码分析:全集整理

Spring版本:5.2.5.RELEASE

【Spring】AOP实现原理(三):创建代理的更多相关文章

  1. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  2. 循序渐进之Spring AOP(1) - 原理

    AOP全称是Aspect Oriented Programing,通常译为面向切面编程.利用AOP可以对面向对象编程做很好的补充. 用生活中的改装车比喻,工厂用面向对象的方法制造好汽车后,车主往往有些 ...

  3. Spring框架系列(10) - Spring AOP实现原理详解之AOP代理的创建

    上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor).本文在此基 ...

  4. Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现

    上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...

  5. Spring AOP学习笔记04:AOP核心实现之创建代理

    上文中,我们分析了对所有增强器的获取以及获取匹配的增强器,在本文中我们就来分析一下Spring AOP中另一部分核心逻辑--代理的创建.这部分逻辑的入口是在wrapIfNecessary()方法中紧接 ...

  6. Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现

    我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...

  7. spring AOP底层原理实现——jdk动态代理

    spring AOP底层原理实现——jdk动态代理

  8. 【Spring】Spring AOP实现原理

    Spring AOP实现原理 在之前的一文中介绍过Spring AOP的功能使用,但是没有深究AOP的实现原理,今天正好看到几篇好文,于是就自己整理了一下AOP实现的几种方式,同时把代理模式相关知识也 ...

  9. Spring AOP 实现原理

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  10. Spring AOP底层原理

    ------------------siwuxie095                                 Spring AOP 底层原理         AOP 即 Aspect Or ...

随机推荐

  1. npm使用淘宝镜像源

    npm使用淘宝镜像源 单次使用 npm install koa --registry=https://registry.npm.taobao.org 永久使用 配置淘宝镜像源 npm config s ...

  2. Spring-JdbcTemplate(注入到spring容器)-02

    1.导入spring-jdbc和spring-tx坐标 <dependency> <groupId>junit</groupId> <artifactId&g ...

  3. 异步任务-springboot

    异步任务-springboot 异步:异步与同步相对,当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作.也就是说无论异步方法执行代码需要多长时间,跟主线程没有任何影响,主线程 ...

  4. git设置本地与远程分支关联

    1.为了避免每次都进行验证,在git进行绑定ssh mkdir ~/.ssh ssh-keygen -t rsa -C "xxx@qq.com" 将生成的公钥粘贴到git中 2.本 ...

  5. openoffice将word转pdf中文乱码或消失的坑

    将windows系统下的中文字体文件(C:\Windows\Fonts),放到/usr/share/fonts下,必须重启openoffice.

  6. Codeforces Round #707 (Div. 2)A.英语漏洞 + C.Going Home C题收获不小

    A题英语漏洞 A题传送门: https://codeforces.com/contest/1501/problem/A 其实题目说的很明白, 只是我傻傻的会错了意, 话不多说, 开整. 前两行是说, ...

  7. Java语言学习day28--8月03日

    ###10接口作为方法参数与返回值 * A:  接口作为方法参数 接口作为方法参数的情况是很常见的,经常会碰到.当遇到方法参数为接口类型时,那么该方法要传入一个接口实现类对象.如下代码演示. //接 ...

  8. delaycall.js 修改表单延迟自动提交的 jQuery / Zepto 插件

    delaycall.js delaycall 是一个 jQuery / Zepto 插件,用于在用户完成某项操作后,延迟指定秒数后自动调动指定函数.如用户输入完内容后,延迟1秒,自动提交表单. Git ...

  9. Azure Terraform(十一)Azure DevOps Pipeline 内的动态临时变量的使用

    思路浅析 在我们分析的 Azure Terraform 系列文中有介绍到关于 Terraform 的状态文件远程存储的问题,我们在  Azure DevOps Pipeline 的 Task Job ...

  10. go-micro集成链路跟踪的方法和中间件原理

    前几天有个同学想了解下如何在go-micro中做链路跟踪,这几天正好看到wrapper这块,wrapper这个东西在某些框架中也称为中间件,里边有个opentracing的插件,正好用来做链路追踪.o ...