在主配置类中添加@EnableAspectJAutoProxy注解,开启aop支持,那么@EnableAspectJAutoProxy到底作了什么?接下来分析下:html
@EnableAspectJAutoProxy点进去以下:git
此时看到了咱们很是熟悉的@Import注解,@Import(AspectJAutoProxyRegistrar.class),进入到AspectJAutoProxyRegistrar发现实现了ImportBeanDefinitionRegistrar以下:spring
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { /** * Register, escalate, and configure the AspectJ auto proxy creator based on the value * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing * {@code @Configuration} class. */ @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }
会调用registerBeanDefinitions方法,跟进到这个方法里面,主要做用就是往Spring容器中注册AnnotationAwareAspectJAutoProxyCreator的Bean的定义信息:express
因此在建立AnnotationAwareAspectJAutoProxyCreatorBean的过程当中初始化方法里面会调用setBeanFactory方法:设计模式
在setBeanFactory方法里面调用initBeanFactory来初始化通知者检索帮助类,后面检索通知会用到。数组
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory); }
该接口定义了2个方法:postProcessBeforeInstantiation和postProcessAfterInstantiation,因此AbstractAutoProxyCreator实现了这2个方法;还记得咱们在Spring IoC源码解析篇分析到以下代码:缓存
resolveBeforeInstantiation方法进去就会调到AbstractAutoProxyCreator的postProcessBeforeInstantiation方法app
/** * 在建立Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化先后) * AOP解析切面以及事务解析事务注解都是在这里完成的 * @param beanClass 当前正在建立的Bean的Class对象 * @param beanName beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { //构建咱们的缓存key Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { //若是被解析过直接返回 if (this.advisedBeans.containsKey(cacheKey)) { return null; } /** * 判断是否是基础的Bean(Advice、PointCut、Advisor、AopInfrastructureBean)是就直接跳过 * 判断是否是应该跳过 (AOP解析直接解析出咱们的切面信息(而且把咱们的切面信息进行缓存),而事务在这里是不会解析的) */ if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null; }
接下来进入到shouldSkip(beanClass, beanName)方法(很重要):ide
protected boolean shouldSkip(Class<?> beanClass, String beanName) { /** * 找到候选的Advisors(通知者或者加强器对象) */ List<Advisor> candidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } return super.shouldSkip(beanClass, beanName); }
接下来看如何找候选的Advisors,findCandidateAdvisors()方法以下:post
@Override protected List<Advisor> findCandidateAdvisors() { //找出事务相关的advisor List<Advisor> advisors = super.findCandidateAdvisors(); //找出Aspect相关的信息以后封装为一个advisor if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } //返回咱们全部的通知 return advisors; }
第一步找事务相关的Advisor:
protected List<Advisor> findCandidateAdvisors() { Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); /** * 经过通知者检测帮助类来帮助咱们找到通知 * */ return this.advisorRetrievalHelper.findAdvisorBeans(); }
第二步找构建AspectJAdvisors:
/** * 去容器中获取到全部的切面信息保存到缓存中 */ public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; //缓存字段aspectNames没有值 注意实例化第一个单实例bean的时候就会触发解析切面 if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { //用于保存全部解析出来的Advisors集合对象 List<Advisor> advisors = new ArrayList<>(); //用于保存切面的名称的集合 aspectNames = new ArrayList<>(); /** * AOP功能中在这里传入的是Object对象,表明去容器中获取到全部的组件的名称,而后再 * 进行遍历,这个过程是十分的消耗性能的,因此说Spring会再这里加入了保存切面信息的缓存。 * 可是事务功能不同,事务模块的功能是直接去容器中获取Advisor类型的,选择范围小,且不消耗性能。 * 因此Spring在事务模块中没有加入缓存来保存咱们的事务相关的advisor */ String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); //遍历咱们从IOC容器中获取处的全部Bean的名称 for (String beanName : beanNames) { if (!isEligibleBean(beanName)) { continue; } //经过beanName去容器中获取到对应class对象 Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } //根据class对象判断是否是切面 @Aspect if (this.advisorFactory.isAspect(beanType)) { //是切面类 //加入到缓存中 aspectNames.add(beanName); //把beanName和class对象构建成为一个AspectMetadata AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { //构建切面注解的实例工厂 MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //真正的去获取咱们的Advisor 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 ArrayList<>(); 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; }
① org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#isAspect:
② 真正的去获取咱们的Advisor,this.advisorFactory.getAdvisors(factory)方法以下:
@Override public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //获取咱们的标记为Aspect的类 Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //获取咱们的切面类的名称 String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //校验咱们的切面类 validate(aspectClass); //咱们使用的是包装模式来包装咱们的MetadataAwareAspectInstanceFactory构建为MetadataAwareAspectInstanceFactory MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new ArrayList<>(); //获取到切面类中的全部方法,可是该方法不会解析到标注了@PointCut注解的方法 for (Method method : getAdvisorMethods(aspectClass)) { //循环解析咱们切面中的方法 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; }
获取切面上的通知方法,并按照规则排序,getAdvisorMethods(aspectClass):
private List<Method> getAdvisorMethods(Class<?> aspectClass) { final List<Method> methods = new ArrayList<>(); ReflectionUtils.doWithMethods(aspectClass, method -> { if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) { methods.add(method); } }); methods.sort(METHOD_COMPARATOR); return methods; }
排序(该顺序在代理调用的时候会用到)规则以下:
根据通知的方法建立加强器:getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName)以下:
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; } //实例化咱们的切面通知对象 return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); }
实例化咱们的切面通知对象,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; //切面的class对象 this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); //切面方法的名称 this.methodName = aspectJAdviceMethod.getName(); //切面方法的参数类型 this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); //切面方法对象 this.aspectJAdviceMethod = aspectJAdviceMethod; //aspectj的通知工厂 this.aspectJAdvisorFactory = aspectJAdvisorFactory; //aspect的实例工厂 this.aspectInstanceFactory = aspectInstanceFactory; //切面的顺序 this.declarationOrder = declarationOrder; //切面的名称 this.aspectName = aspectName; /** * 判断当前的切面对象是否须要延时加载 */ if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // Static part of the pointcut is a lazy type. Pointcut preInstantiationPointcut = Pointcuts.union( aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); // Make it dynamic: must mutate from pre-instantiation to post-instantiation state. // If it's not a dynamic pointcut, it may be optimized out // by the Spring AOP infrastructure after the first evaluation. this.pointcut = new PerTargetInstantiationModelPointcut( this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { // A singleton aspect. this.pointcut = this.declaredPointcut; this.lazy = false; //将切面中的通知构造为advice通知对象 this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); } }
将切面中的通知构造为advice通知对象,instantiateAdvice(this.declaredPointcut):
获取通知getAdvice方法以下:
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { //获取咱们的切面类的class对象 Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); validate(candidateAspectClass); //获取切面方法上的注解 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); //解析出来的注解信息是否为null if (aspectJAnnotation == null) { return null; } //再次判断是不是切面对象 if (!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()) { //是PointCut注解 那么就抛出异常 由于在外面传递进来的方法已经排除了Pointcut的方法 case AtPointcut: if (logger.isDebugEnabled()) { logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'"); } return null; //环绕通知 构建AspectJAroundAdvice case AtAround: springAdvice = new AspectJAroundAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; //前置通知 构建AspectJMethodBeforeAdvice case AtBefore: springAdvice = new AspectJMethodBeforeAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; //后置通知 AspectJAfterAdvice case AtAfter: springAdvice = new AspectJAfterAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; //返回通知 AspectJAfterReturningAdvice case AtAfterReturning: springAdvice = new AspectJAfterReturningAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { springAdvice.setReturningName(afterReturningAnnotation.returning()); } break; //异常通知 AspectJAfterThrowingAdvice 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); } //设置咱们构建出来的通知对象的相关属性好比DeclarationOrder,在代理调用的时候,责任链顺序上会用到 springAdvice.setAspectName(aspectName); springAdvice.setDeclarationOrder(declarationOrder); String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); if (argNames != null) { springAdvice.setArgumentNamesFromStringArray(argNames); } springAdvice.calculateArgumentBindings(); return springAdvice; }
至此真正的去获取咱们的Advisor方法解析完成,List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
③ 若是该切面是单实例的就加入到缓存中:
④ 遍历全部的切面,将每一个切面的全部的加强器添加在advisors中进行返回:
AbstractAutoProxyCreator.shouldSkip()方法中的List<Advisor> candidateAdvisors = findCandidateAdvisors();返回找到的候选的加强器,而后再调用父类的shouldSkip()返回false,就是不跳过的意思
执行完shouldSkip()返回到AbstractAutoProxyCreator.postProcessBeforeInstantiation的方法,至此postProcessBeforeInstantiation执行完成。
该接口有2个方法:postProcessBeforeInitialization和postProcessAfterInitialization,其中在postProcessAfterInitialization方法主要就是经过前面建立的加强器来建立代理对象
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { //获取缓存key Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { //若是有必要就代理 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
进入若是必要就代理方法,wrapIfNecessary(bean, beanName, cacheKey):
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; } //是否是基础的bean 是否是须要跳过的 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } //若是有匹配的通知,就建立代理对象 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //若是不为空,表述须要代理 if (specificInterceptors != DO_NOT_PROXY) { //设置当前的对象已处理 this.advisedBeans.put(cacheKey, Boolean.TRUE); //建立咱们的真正的代理对象 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; }
① 获取匹配的通知方法,getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null):
protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { //找合适的加强器对象 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); //若为空表示没找到 if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }
跟进到找合适的加强器对象方法,findEligibleAdvisors(beanClass, beanName):
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { //找到Spring IoC容器中全部的候选通知 List<Advisor> candidateAdvisors = findCandidateAdvisors(); //判断找到的通知能不能做用到当前的类上 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); //对咱们的advisor进行排序 if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
跟进到判断找到的通知能不能做用到当前的类上方法,findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName):
protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { //从候选的通知器中找到合适正在建立的实例对象的通知器 return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } }
跟进到从候选的通知器中找到合适正在建立的实例对象的通知器方法,AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass):
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { //若候选的加强器集合为空 直接返回 if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } //定义一个合适的加强器集合对象 List<Advisor> eligibleAdvisors = new ArrayList<>(); //循环咱们候选的加强器对象 for (Advisor candidate : candidateAdvisors) { //判断咱们的加强器对象是否是实现了IntroductionAdvisor (很明显咱们事务的没有实现 因此不会走下面的逻辑) if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } //不为空 boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { //判断咱们的加强器对象是否是实现了IntroductionAdvisor (很明显咱们事务的没有实现 因此不会走下面的逻辑) if (candidate instanceof IntroductionAdvisor) { //在上面已经处理过 ,不须要处理 continue; } /** * 真正的判断加强器是否合适当前类型 */ if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
跟进到是否能用方法,canApply(candidate, clazz, hasIntroductions):
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { //判断咱们的加强器是不是IntroductionAdvisor if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } //判断咱们事务的加强器BeanFactoryTransactionAttributeSourceAdvisor是否实现了PointcutAdvisor else if (advisor instanceof PointcutAdvisor) { //转为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; } }
跟进到找到真正能用的加强器方法,canApply(pca.getPointcut(), targetClass, hasIntroductions):
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 introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } //建立一个集合用于保存targetClass的class对象 Set<Class<?>> classes = new LinkedHashSet<>(); //判断当前class是否是代理的class对象 if (!Proxy.isProxyClass(targetClass)) { //加入到集合中去 classes.add(ClassUtils.getUserClass(targetClass)); } //获取到targetClass所实现的接口的class对象,而后加入到集合中 classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); //循环全部的class对象 for (Class<?> clazz : classes) { //经过class获取到全部的方法 Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); //循环咱们的方法 for (Method method : methods) { //经过methodMatcher.matches来匹配咱们的方法 if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : //经过方法匹配器进行匹配 methodMatcher.matches(method, targetClass)) { return true; } } } return false; }
若是该方法返回true就表示匹配,就添加到合适的集合eligibleAdvisors中,遍历完全部的候选加强器后,debug截图以下:
返回到AbstractAdvisorAutoProxyCreator.findEligibleAdvisors方法中,而后扩展加强器,若是合适的加强器列表不是空的就排序。
返回到AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean,若是空就表示不须要代理,不为空就表示须要代理。
② 真正建立代理对象,Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(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); } //建立一个代理对象工厂 ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); //为proxyFactory设置建立jdk仍是cglib代理 if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } //把咱们的specificInterceptors数组中的Advisor转化为数组形式的 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); //为咱们的代理工加入通知器, proxyFactory.addAdvisors(advisors); //设置targetSource对象 proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } //真正建立代理对象 return proxyFactory.getProxy(getProxyClassLoader()); }
跟进到真正建立代理对象方法,proxyFactory.getProxy(getProxyClassLoader()):
public Object getProxy(@Nullable ClassLoader classLoader) { //createAopProxy() 用来建立咱们的代理工厂 return createAopProxy().getProxy(classLoader); }
跟进到建立AOP代理方法,createAopProxy():
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }
跟进到getAopProxyFactory().createAopProxy(this):
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { //判断咱们是否指定使用cglib代理ProxyTargetClass =true 默认false 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."); } //targetClass是接口使用的就是jdk代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } //cglib代理 return new ObjenesisCglibAopProxy(config); } else { //jdk动态代理 return new JdkDynamicAopProxy(config); } }
跟进到建立动态代理(注意这个是jdk的,cglib同理)方法,getProxy(classLoader):
public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); //建立jdk动态代理 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
有没有眼前一亮:该方法用来建立咱们的代理对象,若是proxyTargetClass = true,建立cglib代理 ,为false,若是代理类没有实现接口也建立cglib代理,不然建立jdk代理
至此AnnotationAwareAspectJAutoProxyCreator建立动态代理完成!!
以JdkDynamicAopProxy为例,CGLIB动态代理参照Jdk动态代理自行分析
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]); } //如果hashCode方法不须要代理 else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method itself. return hashCode(); } //如果DecoratingProxy也不要拦截器执行 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; /** * 这个配置是暴露咱们的代理对象到线程变量中,须要搭配@EnableAspectJAutoProxy(exposeProxy = true)一块儿使用
* 好比在目标对象方法中再次获取代理对象可使用这个AopContext.currentProxy() * 还有的就是事务方法调用事务方法的时候也是用到这个 */ if (this.advised.exposeProxy) { //把咱们的代理对象暴露到线程变量中 oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } //获取咱们的目标对象 target = targetSource.getTarget(); //获取咱们目标对象的class Class<?> targetClass = (target != null ? target.getClass() : null); //把aop的advisor转化为拦截器链 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 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); } } }
跟进到invocation.proceed()方法,该方法的调用用到了递归和责任链设计模式:
public Object proceed() throws Throwable { //从-1开始,下标=拦截器的长度-1的条件知足表示执行到了最后一个拦截器的时候,此时执行目标方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } //获取第一个方法拦截器使用的是前++ Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
跟进到((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this)方法,责任链模式,执行顺序以下:
① ExposeInvocationInterceptor.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable { MethodInvocation oldInvocation = invocation.get(); invocation.set(mi); try { return mi.proceed(); } finally { invocation.set(oldInvocation); } }
② AspectJAfterThrowingAdvice.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable { try { //执行下一个通知/拦截器 return mi.proceed(); } catch (Throwable ex) { //抛出异常 if (shouldInvokeOnThrowing(ex)) { //执行异常通知 invokeAdviceMethod(getJoinPointMatch(), null, ex); } throw ex; } }
③ AfterReturningAdviceInterceptor.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable { //执行下一个通知/拦截器 Object retVal = mi.proceed(); //返回通知方法 this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; }
④ AspectJAfterAdvice.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable { try { //执行下一个通知/拦截器 return mi.proceed(); } finally { //后置通知的方法老是会被执行 缘由就在这finally invokeAdviceMethod(getJoinPointMatch(), null, null); } }
⑤ AspectJAroundAdvice.invoke方法:
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); }
⑥ MethodBeforeAdviceInterceptor.invoke方法:
public Object invoke(MethodInvocation mi) throws Throwable { //执行前置通知的方法 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); //执行下一个通知/拦截器,可是该拦截器是最后一个了,因此会调用目标方法 return mi.proceed(); }
运行的执行顺序以下:
注意:该流程图是以本人的spring系列中的spring-aop模块中的LogAspect为例的。
总结:经过@EnableAspectJAutoProxy注解开启AOP功能,该注解为咱们Spring容器中注册了AnnotationAwareAspectJAuto ProxyCreator组件,AOP的准备和代理建立都在这个组件中完成,AnnotationAwareAspectJAutoProxyCreator继承AbstractAuto ProxyCreator实现了InstantiationAwareBeanPostProcessor接口,在方法postProcessBeforeInstantiation中找到Spring容器中全部的加强器,为建立代理作准备;AnnotationAwareAspectJAutoProxyCreator继承了AbstractAutoProxyCreator实现了BeanPost Processor接口,在方法postProcessAfterInitialization中经过前面找到的候选加强器中找到合适的加强器来建立代理对象,最后调用目标方法,进去到代理对象的invoke方法中进行调用。