AOP的核心概念

由来

AOP是切面的意思,面向对象的思想,设计出来的结构都是树状的,最大程度的提升代码的复用率、扩展性、易读性。但是这里有个问题,树状结构大家都是知道是一种关系型结构,擅长处理关系结构,扩展等方面适合业务功能核心代码的开发。但是对于一些重复的、每个功能都需要用到的功能比如,日志、监控、权限、统计、事务等横向的功能(所有功能都需要的),使用面向对象的思想处理起来的结果就是导致代码重复率高、不易扩展、阅读体验比较差,每次都要看非业务代码。这种情况就适合用切面来处理。因为这个过程和织布机,横向织入横线的过程一样,所以这个过程被称为织入。

关键点

切面的核心点,就是切入点,point,我们需要一个切入点 point cut,围绕这个点进行一些增强处理,可能是前,后,或者环绕式的,这些具体的增强就是advice,而切面 aspect 是包含这两个部分的。但是切面生成之后,如果放到合适的地方,就是需要织入 weaving。

spring中的应用

面向对象的设计中,一个类有两部分组成,成员变量,成员方法。成员变量是属性,运行时标识当前对象的状态,成员方法是action,标识这个类可以做哪些事情。所以AOP增强的最小单位就是成员方法,是对方法的增强。但是方法属于类,所以切入点的通过规则表达式(可以理解过正则表达式)来选定类+方法,具体规则看
所以增强的单位肯定也是方法,可以理解为方法增强。最后的织入过程,我们都知道设计模式中的代理模式,这里就是基于代理模式的思想,通过spring的IOC机制生成代理对象,spring通过IOC获取的都是代理对象,所以很方便的就完成了织入过程。
基于以上的概念,spring aop是分开设计了4种接口

spring中的设计

切入点,主要是用来解析表达式,并且进行类、方法的 match操作,PointCut
增强器,主要用来对方法进行增强:Advice
切面,切入点和增强器的组合具体是流程控制: PointCutAdvisor
织入,获取目标对象是否需要进行代理,如果需要则获取需要进行代理的切面(可能有多个),生成代理对象放入到容器中替换目标对象,AutoProxyCreator

类图

Demo

主入口 main

public class InstalmentApiServer {public static void main(String[] args) {System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");log.info("starting main");ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:context/applicationContext.xml",}, false);IHello testA = (IHello) context.getBean("testA");testA.sayHello();

xml 配置文件

<?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:context="http://www.springframework.org/schema/context"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.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"default-lazy-init="false"><aop:aspectj-autoproxy/><bean id="testA" class="com.xiaomi.mifi.instalment.api.server.TestA" init-method="initMethod"> </bean><bean id="logAspect" class="com.xiaomi.mifi.instalment.api.server.LogAspect" /><!--注册annotation--><context:annotation-config/>
</beans>

切面 LogAspect

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;@Aspect
public class LogAspect {@Around("execution(* com..*(..))")private Object errorHandlerAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("-----------> LogAspect before");Object rs =  joinPoint.proceed();System.out.println("-----------> LogAspect After");return rs;}
}

HelloImpl

public class HelloImpl implements  IHello{@Overridepublic void sayHello() {System.out.println("hello world");}
}

TestA

import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;public class TestA implements InitializingBean , IHello{public TestA() {System.out.println("---->TestA constructor this is ");}@PostConstructpublic void init() {System.out.println("PostConstruct");}public void initMethod() {System.out.println("initMethod");}public void fooA() {System.out.println("----> TestA.fooA this is ");}public void foo() {System.out.println("----> TestA.foo this is ");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet");}@Overridepublic void sayHello() {System.out.println("----> TestA sayHello implement ");}
}

开启aop配置

这个触发操作是由于配置

// spring 配置文件, 启动spring AOP
<beans  // aop 命令空间xmlns:aop="http://www.springframework.org/schema/aop"http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"default-lazy-init="false">// 开启  aop配置
<aop:aspectj-autoproxy/>

aop地址空间映射

org.springframework.aop.config.AopNamespaceHandler
这个类用来解析xml配置文件中,aop开头的配置
这个aop命令空间(http://www.springframework.org/schema/aop) 是如何映射到这个类是通过配置文件spring.handlers,来完成的,这个文件在
srping-aop-4.3.30.jar包的,META-INF 目录下面的,spring会加载所有这个名称的文件,用来解析xml文件中的命令空间的
文件内容

http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

aop属性解析

org.springframework.aop.config.AopNamespaceHandler

@Override
public void init() {// In 2.0 XSD as well as in 2.5+ XSDsregisterBeanDefinitionParser("config", new ConfigBeanDefinitionParser());// 属性  aspectj-autoproxy 的解析registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());// Only in 2.0 XSD: moved to context namespace in 2.5+registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}

aop解析细节

具体的细节就是使用AnnotationAwareAspectJAutoProxyCreator类,去向
BeanDefinitionRegistry把beanDefinition注册到工厂类中,bean的创建过程是先创建bena的定义,通过bean的定义再生成的对象。
通过下面的方法完成类:AnnotationAwareAspectJAutoProxyCreator的注册,所有aop的增强都是通过这个类来完成的如果是通过@Aspect注解,注解的切面。
该类的优先级别是最高级别的,先执行

return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);

生成代理类

AbstractAutoProxyCreator
是 AnnotationAwareAspectJAutoProxyCreator 的祖先类的,实现对类的增强是流程主入口。
AnnotationAwareAspectJAutoProxyCreator本身只处理和Aspect注解相关的事情,充分体现面向对象
抽象、继承,的特点,体现了高扩展能力。

主流程

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
AbstractAutowireCapableBeanFactory.initializeBean
->applyBeanPostProcessorsAfterInitialization
开始执行 .postProcessAfterInitialization

// spring 解决单例循环依赖的时候,会提前注册一个BeanFactory,这里会提前生成代理类
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {Object cacheKey = getCacheKey(bean.getClass(), beanName);// 写入这个map的原因,是为了保证单例,这里提前生成了代理类(因为循环依赖),// A->B->A , 这种情况下,在创建B的时候,会调用这里提前生成A的代理类,// 这个时候B里面的对A的引用已经是新的代理类了,但是A本身的还在初始化的过程中还没完成// 需要完成A的初始化,但是还不能重新生成新的代理类否则就不是单例了,所以这里记录// 在postProcessAfterInitialization的时候,对比引用,如果一样,就不重新生成代理类了// 同时这个方法只会被调用一次,因为单例对象生成过成中会加锁,而且进行缓存,保证创建完成之后// 只会从缓存里面取。同时最终A初始化完成之后,会把最终返回的引用对象体会为这里生成的代理对象,保证单例this.earlyProxyReferences.put(cacheKey, bean);// 生成代理类的具体实现return wrapIfNecessary(bean, beanName, cacheKey);
}// 正常的非循环依赖的对象,都从这里进行AOP的增强
// 这里的循环依赖指的是单例循环依赖(非构造函数依赖)
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);// 1, 如果是循环依赖则remove返回的bean ,和 当前是bean地址一样,这里是false,直接结束// 2, 非循环依赖,那这里remove返回的是null,而bean不为空是先决条件,所以这里返回 true,进行类的增强,生成代理类if (this.earlyProxyReferences.remove(cacheKey) != bean) {// 生成代理类的具体实现return wrapIfNecessary(bean, beanName, cacheKey);}}return bean;
}// 生成代理类
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {if (beanName != null && 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;}// Create proxy if we have advice.//获取需要增强的切面Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if (specificInterceptors != DO_NOT_PROXY) {// 缓存该类,需要 AOP 增强this.advisedBeans.put(cacheKey, Boolean.TRUE);// 生成代理类对象Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors// 被代理的对象,在代理类最后调用, new SingletonTargetSource(bean));// 缓存this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}// 缓存该类,不需要 AOP 增强this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;
}// 生成代理类
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {// 设置属性,把原始类名称,设置到 BeanDefiniiton的属性中if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);// 检查类,是需要代理类,还是代理接口,因为有的类没有接口,只能代理类// java JDK proxy只能代理接口,如果是代理类需要使用cgLib生成子类才行if (!proxyFactory.isProxyTargetClass()) {// 检查类属性是否有生命if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {// 如果实现的类是内部类,最后也会代理类// proxyFactory.setProxyTargetClass(true);evaluateProxyInterfaces(beanClass, proxyFactory);}}// 生成最终的增强器Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);proxyFactory.addAdvisors(advisors);proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}// 生成代理对象return proxyFactory.getProxy(getProxyClassLoader());
}// 检查是否需要代理类
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());boolean hasReasonableProxyInterface = false;for (Class<?> ifc : targetInterfaces) {if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&ifc.getMethods().length > 0) {hasReasonableProxyInterface = true;break;}}// 有需要代理的接口,则添加代理接口,这里有个问题,就是只能代理接口的方法,//   非接口方法无法代理,即使符合pointCut的条件if (hasReasonableProxyInterface) {// Must allow for introductions; can't just set interfaces to the target's interfaces only.for (Class<?> ifc : targetInterfaces) {proxyFactory.addInterface(ifc);}}else {// 否则只能代理类proxyFactory.setProxyTargetClass(true);}
}// 生成最终的advisor
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {// Handle prototypes correctly...// 通过配置文件配置的,目前都是通过注解,所以这里一般都是空的Advisor[] commonInterceptors = resolveInterceptorNames();List<Object> allInterceptors = new ArrayList<Object>();if (specificInterceptors != null) {allInterceptors.addAll(Arrays.asList(specificInterceptors));if (commonInterceptors.length > 0) {if (this.applyCommonInterceptorsFirst) {allInterceptors.addAll(0, Arrays.asList(commonInterceptors));}else {allInterceptors.addAll(Arrays.asList(commonInterceptors));}}}Advisor[] advisors = new Advisor[allInterceptors.size()];for (int i = 0; i < allInterceptors.size(); i++) {// wrap 是进行一次适配的过程,因为要兼容老的切面,所以进行一次兼容处理advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));}return advisors;
}

获取该对象需要增强的切面

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
是 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
的子类,提供和切面相关的逻辑

@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);if (advisors.isEmpty()) {return DO_NOT_PROXY;}return advisors.toArray();
}protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {// 获取所有的切面, 注意是逻辑见AnnotationAwareAspectJAutoProxyCreatorList<Advisor> candidateAdvisors = findCandidateAdvisors();// 取出符合该对象的切面List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);// 扩展切面,这个是因为有一些切面比较老,需要去兼容一些,做一些适配extendAdvisors(eligibleAdvisors);if (!eligibleAdvisors.isEmpty()) {// 切面排序,决定执行先后顺序eligibleAdvisors = sortAdvisors(eligibleAdvisors);}return eligibleAdvisors;
}

获取Aspect所有的切面

对Aspect注解,进行解析,获取所有的Aspect注解,切面
以及表达式
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
主流程

@Override
protected List<Advisor> findCandidateAdvisors() {// 先调用父类接口,兼容父类List<Advisor> advisors = super.findCandidateAdvisors();// 获取Aspect注解的切面advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());return advisors;
}// 获取增强列表,
// 来自类:org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder
public List<Advisor> buildAspectJAdvisors() {List<String> aspectNames = this.aspectBeanNames;if (aspectNames == null) {// 加锁,防止重复操作synchronized (this) {aspectNames = this.aspectBeanNames;// double check if (aspectNames == null) {List<Advisor> advisors = new LinkedList<Advisor>();aspectNames = new LinkedList<String>();// 由于Aspect注解本身无法直接识别,所以通过这种方式获取所有的已经// 这个地方会获取所有的bean,包含继承Object的子类,由于Asject注解,的类本身是没有类型的// 所以这里使用Object获取所有的,调用这个方法会进行缓存//所以没有直接调用this.beanFactory.getBeanDefinitionNames 这个方法String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);for (String beanName : beanNames) {if (!isEligibleBean(beanName)) {continue;}// We must be careful not to instantiate beans eagerly as in this case they// would be cached by the Spring container but would not have been weaved.Class<?> beanType = this.beanFactory.getType(beanName);if (beanType == null) {continue;}// 判断是否有Aspect注解if (this.advisorFactory.isAspect(beanType)) {aspectNames.add(beanName);AspectMetadata amd = new AspectMetadata(beanType, beanName);if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {// 创建工厂类,这个工厂类只包含当前aspect一个beanName,为了后续生成advice使用MetadataAwareAspectInstanceFactory factory =new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);// 解析Aspect注解的类,获取方法上面的注解,每个增强方法都是一个切面增强// 具体的可以看下代码细节,比较简单就是解析 Around After before这些注解List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);if (this.beanFactory.isSingleton(beanName)) {this.advisorsCache.put(beanName, classAdvisors);}else {this.aspectFactoryCache.put(beanName, factory);}advisors.addAll(classAdvisors);}else {// Per target or per this.if (this.beanFactory.isSingleton(beanName)) {throw new IllegalArgumentException("Bean with name '" + beanName +"' is a singleton, but aspect instantiation model is not singleton");}MetadataAwareAspectInstanceFactory factory =new PrototypeAspectInstanceFactory(this.beanFactory, beanName);this.aspectFactoryCache.put(beanName, factory);advisors.addAll(this.advisorFactory.getAdvisors(factory));}}}this.aspectBeanNames = aspectNames;return advisors;}}}if (aspectNames.isEmpty()) {return Collections.emptyList();}List<Advisor> advisors = new LinkedList<Advisor>();for (String aspectName : aspectNames) {// 单例List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);if (cachedAdvisors != null) {advisors.addAll(cachedAdvisors);}else {// 非单例的每次都需要通过工厂类生成新的对象MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);advisors.addAll(this.advisorFactory.getAdvisors(factory));}}return advisors;
}

获取类里面的增强器

// 获取@aspect 注解类中的 advice
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();validate(aspectClass);// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator// so that it will only instantiate once.// 为了延迟初始化对象MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);List<Advisor> advisors = new ArrayList<Advisor>();// 过滤掉pointCut 切面注解, for (Method method : getAdvisorMethods(aspectClass)) {// 获取所有的注解方法, @around @before等Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);if (advisor != null) {advisors.add(advisor);}}// If it's a per target aspect, emit the dummy instantiating aspect.if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);advisors.add(0, instantiationAdvisor);}// Find introduction fields.for (Field field : aspectClass.getDeclaredFields()) {Advisor advisor = getDeclareParentsAdvisor(field);if (advisor != null) {advisors.add(advisor);}}return advisors;
}
//
@Override
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrderInAspect, String aspectName) {validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());if (expressionPointcut == null) {return null;}// 这里会根据注解 @around before after 生成不同的advice实现类return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}//
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {this.declaredPointcut = declaredPointcut;this.declaringClass = aspectJAdviceMethod.getDeclaringClass();this.methodName = aspectJAdviceMethod.getName();this.parameterTypes = aspectJAdviceMethod.getParameterTypes();this.aspectJAdviceMethod = aspectJAdviceMethod;this.aspectJAdvisorFactory = aspectJAdvisorFactory;this.aspectInstanceFactory = aspectInstanceFactory;this.declarationOrder = declarationOrder;this.aspectName = aspectName;// A singleton aspect.this.pointcut = this.declaredPointcut;this.lazy = false;// 这里进行advice的初始化this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);}
// 实例化增强器 advice
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,this.aspectInstanceFactory, this.declarationOrder, this.aspectName);}
// 根据不同的注解,生成不同的advice实例,代理的时候调用的是这个实例
@Override
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();validate(candidateAspectClass);AspectJAnnotation<?> aspectJAnnotation =AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);if (aspectJAnnotation == null) {return null;}// If we get here, we know we have an AspectJ method.// Check that it's an AspectJ-annotated classif (!isAspect(candidateAspectClass)) {throw new AopConfigException("Advice must be declared inside an aspect type: " +"Offending method '" + candidateAdviceMethod + "' in class [" +candidateAspectClass.getName() + "]");}if (logger.isDebugEnabled()) {logger.debug("Found AspectJ method: " + candidateAdviceMethod);}AbstractAspectJAdvice springAdvice;switch (aspectJAnnotation.getAnnotationType()) {case AtPointcut:if (logger.isDebugEnabled()) {logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");}return null;// around 注解,case AtAround:// 这里把facotyr作为参数放进去,是为了延迟获取实例化对象,等需要的时候再生成springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtBefore:springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtAfter:springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtAfterReturning:springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();if (StringUtils.hasText(afterReturningAnnotation.returning())) {springAdvice.setReturningName(afterReturningAnnotation.returning());}break;case AtAfterThrowing:springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {springAdvice.setThrowingName(afterThrowingAnnotation.throwing());}break;default:throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod);}// Now to configure the advice...springAdvice.setAspectName(aspectName);springAdvice.setDeclarationOrder(declarationOrder);String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);if (argNames != null) {springAdvice.setArgumentNamesFromStringArray(argNames);}springAdvice.calculateArgumentBindings();return springAdvice;
}

获取符合当前bean的切面

pointCut表达式文档

// 匹配符合条件的切面
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {// 设置到 ThrealLocal里面,其他地方会调用这个来进行切面的匹配,从这里获取要增强的类// 决定是否要进行增强ProxyCreationContext.setCurrentProxiedBeanName(beanName);try {return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);}finally {// 清除 ThrealLocalProxyCreationContext.setCurrentProxiedBeanName(null);}
}//  org.springframework.aop.support.AopUtils
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {if (candidateAdvisors.isEmpty()) {return candidateAdvisors;}for (Advisor candidate : candidateAdvisors) {if (candidate instanceof IntroductionAdvisor) {// already processedcontinue;}// Spring Aop Aspect 注解走的都是这里if (canApply(candidate, clazz, hasIntroductions)) {eligibleAdvisors.add(candidate);}}return eligibleAdvisors;
}
//  org.springframework.aop.support.AopUtils
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {if (advisor instanceof IntroductionAdvisor) {return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);}// 走这里,切面增强else if (advisor instanceof PointcutAdvisor) {PointcutAdvisor pca = (PointcutAdvisor) advisor;return canApply(pca.getPointcut(), targetClass, hasIntroductions);}else {// It doesn't have a pointcut so we assume it applies.return true;}
}//  org.springframework.aop.support.AopUtils
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {Assert.notNull(pc, "Pointcut must not be null");// 类过滤,如果类不符合条件,直接结束,看了一点没看明白,大概意思就是进行字符串匹配,// 但是匹配方式比较复杂if (!pc.getClassFilter().matches(targetClass)) {return false;}MethodMatcher methodMatcher = pc.getMethodMatcher();if (methodMatcher == MethodMatcher.TRUE) {// No need to iterate the methods if we're matching any method anyway...return true;}IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;if (methodMatcher instanceof IntroductionAwareMethodMatcher) {introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;}// 获取该类的实现的所有接口类Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));// 把当前类添加进去classes.add(targetClass);// 遍历当前类以及其所有接口类的,所有方法,先遍历接口,最后遍历当前类for (Class<?> clazz : classes) {Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);for (Method method : methods) {if ((introductionAwareMethodMatcher != null &&// 方法匹配,具体实现细节没有看懂introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||// 更大范围的匹配,大概就是把类,入参,返回值等拆成不同的token 进行匹配,具体实现细节没有看懂methodMatcher.matches(method, targetClass)) {// 只要有一个方法符合条件则直接返回,快速返回,// 因为只要有一个就必须生成代理类了,没必要遍历所有的方法return true;}}}return false;
}

获取代理工厂生成代理类

// 来自 org.springframework.aop.framework.DefaultAopProxyFactory
// 先根据配置,或者当前类的情况,生成代理工厂类,如果该类一个自定义接口都没有实现
// 则会使用CGLib进行代理,通过生成子类的方式,增强需要增强的方法。
// 否则使用JDk动态代理工厂类,但是该类只会生成接口包含的方法的代理类,不会对实现类内所有方法都进行代理
// 总之都是有条件的,对于符合条件的方法进行代理。但是JDK动态代理生成的代理对象的类型必须是其实现的
// 接口否则会因为类型不匹配报错。
@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.");}if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}// 代理类,使用Cglibreturn new ObjenesisCglibAopProxy(config);}else {//代理接口,JDK动态代理return new JdkDynamicAopProxy(config);}
}// 来自 org.springframework.aop.framework.JdkDynamicAopProxy
@Override
public Object getProxy(ClassLoader classLoader) {// 获取所有需要代理的接口,这里会新增一些springAOP特有的接口Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);// 检查、标识,是否有,equal ,hashCode, 方法,没有需要特殊处理findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);// 使用JDK动态代理,生成代理类,具体的可以看下面的生成的代理类// 这里使用this当前对象是因为,具体的操作要由该对象来完成,每个需要代理的对象都会新生成一个该对象//该类实现了InvocationHandler接口,具体代理在invoder方法中 final class JdkDynamicAopProxy implements AopProxy, InvocationHandler,  {return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
// 来自  org.springframework.aop.framework.AopProxyUtils
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();if (specifiedInterfaces.length == 0) {// No user-specified interfaces: check whether target class is an interface.Class<?> targetClass = advised.getTargetClass();if (targetClass != null) {if (targetClass.isInterface()) {advised.setInterfaces(targetClass);}else if (Proxy.isProxyClass(targetClass)) {advised.setInterfaces(targetClass.getInterfaces());}specifiedInterfaces = advised.getProxiedInterfaces();}}// 如果没有,则需要代理该接口, 该接口没有具体方法,只是用来标识是是最顶层的抽象定义接口,划分类别boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);// 如果没有,则需要代理该接口, 这个里面有所有增强器需要的基础方法,但是默认JDK动态代理都已经实现了boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);// 如果没有,则需要代理该接口boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));int nonUserIfcCount = 0;if (addSpringProxy) {nonUserIfcCount++;}if (addAdvised) {nonUserIfcCount++;}if (addDecoratingProxy) {nonUserIfcCount++;}Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);int index = specifiedInterfaces.length;if (addSpringProxy) {proxiedInterfaces[index] = SpringProxy.class;index++;}if (addAdvised) {proxiedInterfaces[index] = Advised.class;index++;}if (addDecoratingProxy) {proxiedInterfaces[index] = DecoratingProxy.class;}return proxiedInterfaces;}
// 来自    org.springframework.aop.framework.DefaultAopProxyFactory
// 查找其接口中,是否包含的有 equal , hashCode 两个方法
// 因为要是没有的话就需要进行特殊处理,因为这两个方法是必须要要有的,属于所有对象都有的
// 因为所有对象都继承自 Object类
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {for (Class<?> proxiedInterface : proxiedInterfaces) {Method[] methods = proxiedInterface.getDeclaredMethods();for (Method method : methods) {if (AopUtils.isEqualsMethod(method)) {this.equalsDefined = true;}if (AopUtils.isHashCodeMethod(method)) {this.hashCodeDefined = true;}if (this.equalsDefined && this.hashCodeDefined) {return;}}}}

JDK动态代理生成的代理类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.sun.proxy;import com.xiaomi.mifi.instalment.api.server.IHello;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.DecoratingProxy;public final class $Proxy9 extends Proxy implements InitializingBean, IHello, SpringProxy, Advised, DecoratingProxy {private static Method m1;private static Method m15;private static Method m26;private static Method m22;private static Method m17;private static Method m12;private static Method m5;private static Method m21;private static Method m10;private static Method m9;private static Method m0;private static Method m13;private static Method m19;private static Method m25;private static Method m23;private static Method m2;private static Method m27;private static Method m14;private static Method m28;private static Method m16;private static Method m6;private static Method m7;private static Method m18;private static Method m24;private static Method m4;private static Method m3;private static Method m20;private static Method m8;private static Method m11;public $Proxy9(InvocationHandler var1) throws  {super(var1);}public final boolean equals(Object var1) throws  {try {// super.h 指的是org.springframework.aop.framework.JdkDynamicAopProxy// 类生成的对象,invoder 就是其invoder方法,具体看下面的调用流程return (Boolean)super.h.invoke(this, m1, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final void addAdvisor(Advisor var1) throws AopConfigException {try {super.h.invoke(this, m15, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final boolean isExposeProxy() throws  {try {return (Boolean)super.h.invoke(this, m26, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final boolean isProxyTargetClass() throws  {try {return (Boolean)super.h.invoke(this, m22, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final void removeAdvisor(int var1) throws AopConfigException {try {super.h.invoke(this, m17, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final Class[] getProxiedInterfaces() throws  {try {return (Class[])super.h.invoke(this, m12, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final int indexOf(Advisor var1) throws  {try {return (Integer)super.h.invoke(this, m5, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final TargetSource getTargetSource() throws  {try {return (TargetSource)super.h.invoke(this, m21, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final void addAdvice(int var1, Advice var2) throws AopConfigException {try {super.h.invoke(this, m10, new Object[]{var1, var2});} catch (RuntimeException | Error var4) {throw var4;} catch (Throwable var5) {throw new UndeclaredThrowableException(var5);}}public final void addAdvice(Advice var1) throws AopConfigException {try {super.h.invoke(this, m9, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final int hashCode() throws  {try {return (Integer)super.h.invoke(this, m0, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final boolean isInterfaceProxied(Class var1) throws  {try {return (Boolean)super.h.invoke(this, m13, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final boolean removeAdvice(Advice var1) throws  {try {return (Boolean)super.h.invoke(this, m19, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final void setExposeProxy(boolean var1) throws  {try {super.h.invoke(this, m25, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final void setTargetSource(TargetSource var1) throws  {try {super.h.invoke(this, m23, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final String toString() throws  {try {return (String)super.h.invoke(this, m2, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final Class getTargetClass() throws  {try {return (Class)super.h.invoke(this, m27, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final void addAdvisor(int var1, Advisor var2) throws AopConfigException {try {super.h.invoke(this, m14, new Object[]{var1, var2});} catch (RuntimeException | Error var4) {throw var4;} catch (Throwable var5) {throw new UndeclaredThrowableException(var5);}}public final Class getDecoratedClass() throws  {try {return (Class)super.h.invoke(this, m28, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final boolean removeAdvisor(Advisor var1) throws  {try {return (Boolean)super.h.invoke(this, m16, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final int indexOf(Advice var1) throws  {try {return (Integer)super.h.invoke(this, m6, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final boolean isFrozen() throws  {try {return (Boolean)super.h.invoke(this, m7, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final boolean replaceAdvisor(Advisor var1, Advisor var2) throws AopConfigException {try {return (Boolean)super.h.invoke(this, m18, new Object[]{var1, var2});} catch (RuntimeException | Error var4) {throw var4;} catch (Throwable var5) {throw new UndeclaredThrowableException(var5);}}public final void setPreFiltered(boolean var1) throws  {try {super.h.invoke(this, m24, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final void sayHello() throws  {try {super.h.invoke(this, m4, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final void afterPropertiesSet() throws Exception {try {super.h.invoke(this, m3, (Object[])null);} catch (Exception | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final String toProxyConfigString() throws  {try {return (String)super.h.invoke(this, m20, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final Advisor[] getAdvisors() throws  {try {return (Advisor[])super.h.invoke(this, m8, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final boolean isPreFiltered() throws  {try {return (Boolean)super.h.invoke(this, m11, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}static {try {m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));m15 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvisor", Class.forName("org.springframework.aop.Advisor"));m26 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isExposeProxy");m22 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isProxyTargetClass");m17 = Class.forName("org.springframework.aop.framework.Advised").getMethod("removeAdvisor", Integer.TYPE);m12 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getProxiedInterfaces");m5 = Class.forName("org.springframework.aop.framework.Advised").getMethod("indexOf", Class.forName("org.springframework.aop.Advisor"));m21 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getTargetSource");m10 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvice", Integer.TYPE, Class.forName("org.aopalliance.aop.Advice"));m9 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvice", Class.forName("org.aopalliance.aop.Advice"));m0 = Class.forName("java.lang.Object").getMethod("hashCode");m13 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isInterfaceProxied", Class.forName("java.lang.Class"));m19 = Class.forName("org.springframework.aop.framework.Advised").getMethod("removeAdvice", Class.forName("org.aopalliance.aop.Advice"));m25 = Class.forName("org.springframework.aop.framework.Advised").getMethod("setExposeProxy", Boolean.TYPE);m23 = Class.forName("org.springframework.aop.framework.Advised").getMethod("setTargetSource", Class.forName("org.springframework.aop.TargetSource"));m2 = Class.forName("java.lang.Object").getMethod("toString");m27 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getTargetClass");m14 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvisor", Integer.TYPE, Class.forName("org.springframework.aop.Advisor"));m28 = Class.forName("org.springframework.core.DecoratingProxy").getMethod("getDecoratedClass");m16 = Class.forName("org.springframework.aop.framework.Advised").getMethod("removeAdvisor", Class.forName("org.springframework.aop.Advisor"));m6 = Class.forName("org.springframework.aop.framework.Advised").getMethod("indexOf", Class.forName("org.aopalliance.aop.Advice"));m7 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isFrozen");m18 = Class.forName("org.springframework.aop.framework.Advised").getMethod("replaceAdvisor", Class.forName("org.springframework.aop.Advisor"), Class.forName("org.springframework.aop.Advisor"));m24 = Class.forName("org.springframework.aop.framework.Advised").getMethod("setPreFiltered", Boolean.TYPE);m4 = Class.forName("com.xiaomi.mifi.instalment.api.server.IHello").getMethod("sayHello");m3 = Class.forName("org.springframework.beans.factory.InitializingBean").getMethod("afterPropertiesSet");m20 = Class.forName("org.springframework.aop.framework.Advised").getMethod("toProxyConfigString");m8 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getAdvisors");m11 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isPreFiltered");} catch (NoSuchMethodException var2) {throw new NoSuchMethodError(var2.getMessage());} catch (ClassNotFoundException var3) {throw new NoClassDefFoundError(var3.getMessage());}}
}

动态代理调用流程

注意,这里只能代理接口,生成的代理类继承 com.sun.Proxy 类,生成的代理方法来自于接口,而不是实现类,所以如果在实现类外面引用了实现类,而不是接口,这个类还被增强 了,那就会报错。提示
com.sun.Proxy 无法转换为需要的类型。就是因为这个原因。但是类内部的方法调用是不影响,属于内部调用(内部调用使用的是实现类对象的而不是代理对象,所以没有影响。
org.springframework.aop.framework.JdkDynamicAopProxy

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;// 被代理的对象,testATargetSource targetSource = this.advised.targetSource;Class<?> targetClass = null;Object target = null;try {// 之前检查做的标记,如果没有equal方法,并且正在调用则进行特殊处理,这里if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {// The target does not implement the equals(Object) method itself.// 这里的比较还是比较特殊的,可以看看,会对比很多东西,不会对比hashCodereturn equals(args[0]);}// 之前检查做的标记,如果没有hashCode 方法,并且正在调用则进行特殊处理else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {// 使用当前对象的hashCode,加上 被代理对象的hashCode保证其唯一性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();}// 这里获取的就是advice列表了,比如 AspectJAroundAdviceList<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);// 没有需要代理的则直接调用被代理对象就好了if (chain.isEmpty()) {// 对于Strig ..args这种可变参数,进行兼容处理Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);// 反射调用方法retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);}else {// 生成代理调用类,通过下标,根据filter这种链式调用,执行所有代理invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, 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);}}
}// 来自: org.springframework.aop.framework.ReflectiveMethodInvocation
@Override
public Object proceed() throws Throwable {// 最后执行,被代理对象的方法if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}// 从-1开始,所以先加+1,再使用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 {// aroundAdvice这种都是实现了MethodInterceptor接口,走这里return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}
}//  org.springframework.aop.aspectj.AspectJAroundAdvice
@Override
public Object invoke(MethodInvocation mi) throws Throwable {if (!(mi instanceof ProxyMethodInvocation)) {throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);}ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);JoinPointMatch jpm = getJoinPointMatch(pmi);return invokeAdviceMethod(pjp, jpm, null, null);
}// org.springframework.aop.aspectj.AbstractAspectJAdvice
// 调用切面增强器方法
protected Object invokeAdviceMethod(JoinPoint jp, JoinPointMatch jpMatch, Object returnValue, Throwable t)throws Throwable {// argBinding 进行参数的绑定return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {Object[] actualArgs = args;if (this.aspectJAdviceMethod.getParameterTypes().length == 0) {actualArgs = null;}try {ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);// this.aspectInstanceFactory.getAspectInstance() 通过前面创建的工厂类,获取增强器的额对象// 通过反射执行增强器的方法, 因为 around里面会继续调用 jointPoint.process()方法,所以这里不需要显示调用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();}
}

SpringAop 流程源码阅读相关推荐

  1. Activity启动流程源码分析-浅析生命周期函数

    源码分析 接着上一篇 Activity启动流程源码分析-setContentView源码阅读 的讲解,本节介绍一下Activity的生命周期函数何时被调用 要看Activity的生命周期函数何时被调用 ...

  2. 云原生小课堂|Envoy请求流程源码解析(三):请求解析

    ​ 前言 Envoy 是一款面向 Service Mesh 的高性能网络代理服务.它与应用程序并行运行,通过以平台无关的方式提供通用功能来抽象网络.当基础架构中的所有服务流量都通过 Envoy 网格时 ...

  3. SpringBoot2 | SpringBoot启动流程源码分析(一)

    首页 博客 专栏·视频 下载 论坛 问答 代码 直播 能力认证 高校 会员中心 收藏 动态 消息 创作中心 SpringBoot2 | SpringBoot启动流程源码分析(一) 置顶 张书康 201 ...

  4. OkHttp原理流程源码分析

    OkHttp已经是非常流行的android客户端的网络请求框架,我其实在项目中使用也已经好几年了,之前一直把重心放在如何快速的搞定业务上.迭代的效率上,这一点来讲,对于一个公司优秀员工是没有毛病的.但 ...

  5. Myth源码解析系列之六- 订单下单流程源码解析(发起者)

    前面一章我们走完了服务启动的源码,这次我们进入下单流程的源码解析~ 订单下单流程源码解析(发起者) 首先保证myth-demo-springcloud-order.myth-demo-springcl ...

  6. springsecurity不拦截某个接口_SpringSecurity 默认表单登录页展示流程源码

    SpringSecurity 默认表单登录页展示流程源码 本篇主要讲解 SpringSecurity提供的默认表单登录页 它是如何展示的的流程,涉及1.FilterSecurityIntercepto ...

  7. 【源码分析】storm拓扑运行全流程源码分析

    [源码分析]storm拓扑运行全流程源码分析 @(STORM)[storm] 源码分析storm拓扑运行全流程源码分析 一拓扑提交流程 一stormpy 1storm jar 2def jar 3ex ...

  8. hadoop源码分析_Spark2.x精通:Job触发流程源码深度剖析(一)

    , 一.概述  之前几篇文章对Spark集群的Master.Worker启动流程进行了源码剖析,后面直接从客户端角度出发,讲解了spark-submit任务提交过程及driver的启动:集群启动.任务 ...

  9. android系统加载主题的流程,详解Android布局加载流程源码

    一.首先看布局层次 看这么几张图 我们会发现DecorView里面包裹的内容可能会随着不同的情况而变化,但是在Decor之前的层次关系都是固定的.即Activity包裹PhoneWindow,Phon ...

最新文章

  1. uscao Mother's Milk
  2. 用电脑发短信_重磅!一个软件实现电脑上接打手机电话、收发短信、传文件、屏幕镜像!...
  3. 解决工控网络通信协议威胁的实践
  4. Mac下github的使用
  5. Ubuntu18.04安装JDK1.8和maven3
  6. 斯坦福大学机器学习第四课“逻辑回归(Logistic Regression)”
  7. MySQL存储树形数据优化技笔记
  8. 六款值得推荐的Android开源框架简介
  9. 持久化雪花视图实例学习
  10. springcloud多租户实现原理-Saas多租户实现-以及几种方案_设计思路---springcloud工作笔记108
  11. Qt5学习笔记之bin文件合成工具二:bin文件的读取和写入
  12. Python pickle模块学习(超级详细)
  13. 基于STM32设计的酒驾报警系统
  14. WORD 毕设页眉页码目录标题 排版
  15. 【扫盲】Pulse消除马赛克(老司机福利)
  16. MySQL里Wating for Slave workers to free pending events到底在等什么
  17. 0024-华为OD机考:身高--体重排序
  18. 吃货制霸地图生成 美食标注 中国制霸数据生成器
  19. 【数学建模】数学建模中的常用工具推荐
  20. 对期权价格计算的实现方式的思考

热门文章

  1. LTE default bearer dedicated bearer and radio bearer
  2. RabbitMQ ——基于Stomp实现与MQTT客户端通信
  3. CLIP4Clip: An Empirical Study of CLIP for End to End Video Clip Retrieval
  4. 第六章、FOR、IF和while
  5. 物联网通信协议(接入协议)
  6. win10设置虚拟内存_原来win10这样设置,电脑就能释放30G,比win7运行还顺畅
  7. 啧啧啧……JAVA你看看你……
  8. python爬虫——使用selenium爬取微博数据(一)
  9. IOS版的MT4软件如何下载安装
  10. 经济机器是怎么运行的