java源码 - Spring5.x(4)之 AOP

官方文档

1. AOP示例

在这里插入图片描述

//被增强的目标对象
@Component//AspectJ注解方式
@Aspect
public class AspectAdviceBeanUseAnnotation {

    // 定义一个全局的Pointcut
    @Pointcut("execution(* com.lyq.config.aopconfig.*.do*(..))")
    public void doMethods() {
    }

    // 定义一个全局的Pointcut
    @Pointcut("execution(* com.lyq.config.aopconfig.*.service*(..))")
    public void services() {
    }

    // 定义一个Before Advice
    @Before("doMethods() and args(tk,..)")
    public void before3(String tk) {
        System.out.println("----------- AspectAdviceBeanUseAnnotation before3  增强  参数tk= " + tk);
    }

    //环绕增强
    @Around("services() and args(name,..)")
    public Object around2(ProceedingJoinPoint pjp, String name) throws Throwable {
        System.out.println("--------- AspectAdviceBeanUseAnnotation arround2 参数 name=" + name);
        System.out.println("----------- AspectAdviceBeanUseAnnotation arround2 环绕-前增强 for " + pjp);
        Object ret = pjp.proceed();
        System.out.println("----------- AspectAdviceBeanUseAnnotation arround2 环绕-后增强 for " + pjp);
        return ret;
    }

    @AfterReturning(pointcut = "services()", returning = "retValue")
    public void afterReturning(Object retValue) {
        System.out.println("----------- AspectAdviceBeanUseAnnotation afterReturning 增强 , 返回值为: " + retValue);
    }

    @AfterThrowing(pointcut = "services()", throwing = "e")
    public void afterThrowing(JoinPoint jp, Exception e) {
        System.out.println("----------- AspectAdviceBeanUseAnnotation afterThrowing 增强  for " + jp);
        System.out.println("----------- AspectAdviceBeanUseAnnotation afterThrowing 增强  异常 :" + e);
    }

    @After("doMethods()")
    public void after(JoinPoint jp) {
        System.out.println("----------- AspectAdviceBeanUseAnnotation after 增强  for " + jp);
    }

}

如果是注解模式请在配置类上加入:

@EnableAspectJAutoProxy

如果是配置文件:

<aop: aspectj-autoproxy>

这里配置了这个,Spring会启动AspectJAutoProxyBeanDefinitionParser来进行解析。

2. AspectJAutoProxyBeanDefinitionParser

入口函数为:parse

class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {

	@Override
	@Nullable
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
		extendBeanDefinition(element, parserContext);
		return null;
	}
}

其中比较重要的就是registerAspectJAnnotationAutoProxyCreatorIfNecessary方法:

public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			ParserContext parserContext, Element sourceElement) {
	//注册或升级 AutoProxyCreator 定义 beanName为org.Springframework.aop.config.internalAutoProxyCreator的BeanDefinition
		BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
				parserContext.getRegistry(), parserContext.extractSource(sourceElement));
		//对于 proxy-target-class 以及 expose-proxy 属性的处理
		useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
		//注册组件并通知,便于监听器做进一步处理
		registerComponentIfNecessary(beanDefinition, parserContext);
	}

在这个方法里主要做了三件事情:

  1. 注册或者升级 AnnotationAwareAspectJAutoProxyCreator
    对于 AOP 的实现,基本上都是靠 AnnotationAwareAspectJAutoProxyCreator 去完成,它可以根据@Point注解定义的切点来自动代理相匹配的 bean。
@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
			@Nullable Object source) {

		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}
	@Nullable
	private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
			@Nullable Object source) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}

		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}
  1. 处理 proxy-target-class 以及 expose-proxy 属性
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
		if (sourceElement != null) {
		//对proxy-target-class属性的处理
			boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
			if (proxyTargetClass) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			//对 expose-proxy 属性的处理
			boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
			if (exposeProxy) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
		}
	}

那么proxy-target-class是个什么东西呢?

Spring AOP 部分使用 JDK 动态代理或者 CGLIB 来为目标对象创建代理,强制使用 CGLIB 代理需要 <aop:config>的proxy-target class 属性设为 true。

expose-proxy:
目标对象内部的自我调用将无法实施切面中的增强,例如:this指针的方法调用。
这个时候配置<aop : aspectj - autoproxy expose - proxy= ” true ” />,并将代码改为:

(X) AopContext.currentProxy().xxx()

3. AnnotationAwareAspectJAutoProxyCreator

其继承关系如下。

在这里插入图片描述

这种继承图最重要的就是我们可以看到AnnotationAwareAspectJAutoProxyCreator其实是继承了BeanPostProcessor的,那么在Spring加载即getBean的时候会在实例化前调用该AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInstantiation方法。

那我们就来看看这个入口方法:
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
		if (bean != null) {
		//根据给定的bean的class和name构建出一个key,格式:beanClassName_beanName
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
	
	/**
	 * 如有必要,包装给定的bean,即如果它符合代理的条件。
	 * @param 原始bean实例
	 * @param beanName the name of the bean
	 * @param 元数据访问的缓存键
	 * @return a proxy wrapping the bean, or the raw bean instance as-is
	 */
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		//如果根据这个bean能够在targetSourcedBeans中查找到,那么直接返回
		//是否处理过
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		//如果这个bean 不需要增强
			return bean;
		}
		//给定的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

3.1 getAdvicesAndAdvisorsForBean

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
获取指定Bean的增强方法:获取所有的增强以及寻找所有增强中适用于 bean 增强并应用。

@Override
	@Nullable
	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();
	}
//找到自动代理该类的所有合格的Advisor。
	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

3.2 寻找所有Advisors

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors

@Override
	protected List<Advisor> findCandidateAdvisors() {
		//根据超类规则添加找到的所有Spring顾问。
		List<Advisor> advisors = super.findCandidateAdvisors();
		// bean工厂中所有AspectJ方面的构建顾问。
		if (this.aspectJAdvisorsBuilder != null) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}

AnnotationAwareAspectJAutoProxyCreator间接继承AbstractAdvisorAutoProxyCreator。获取增强的方法中除了保留父类的获取配置文件中定义的增强外,同时添加了Bean 注解增强的功能。
org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors

	/**
	*在当前bean工厂中寻找aspectj注释的方面bean,
	*并返回表示它们的Spring AOP顾问列表。
	*为每个AspectJ通知方法创建一个Spring Advisor。
	 * @return the list of {@link org.springframework.aop.Advisor} beans
	 * @see #isEligibleBean
	 */
	public List<Advisor> buildAspectJAdvisors() {
		List<String> aspectNames = this.aspectBeanNames;

		if (aspectNames == null) {
			synchronized (this) {
				aspectNames = this.aspectBeanNames;
				if (aspectNames == null) {
					List<Advisor> advisors = new ArrayList<>();
					aspectNames = new ArrayList<>();
					//获取所有的beanname
					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
							this.beanFactory, Object.class, true, false);
					//循环所有的beanname 找出增强方法
					for (String beanName : beanNames) {
						if (!isEligibleBean(beanName)) {
							continue;
						}
						//我们必须小心不要急于实例化bean,在本例中是它们
						//将被Spring容器缓存,但不会被编织。
						Class<?> beanType = this.beanFactory.getType(beanName);
						if (beanType == null) {
							continue;
						}
						//如果存在AspectJ注解
						if (this.advisorFactory.isAspect(beanType)) {
							aspectNames.add(beanName);
							AspectMetadata amd = new AspectMetadata(beanType, beanName);
							if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
								MetadataAwareAspectInstanceFactory factory =
										new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
								//标记该类中的增强方法
								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;
	}

以上所做的事无非从所有bean内找到AspectJ的类,找到并提取增强,那么重要的来了:

在这里插入图片描述

org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors

@Override
	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
	//获取标记为AspectJ的类
		Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
		//验证
		validate(aspectClass);

		//我们需要用一个装饰器包装元数据
		//这样它只实例化一次。
		MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
				new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

		List<Advisor> advisors = new ArrayList<>();
		for (Method method : getAdvisorMethods(aspectClass)) {
		//声明为pointcut的方法不处理
			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;
	}

getAdvisor

@Override
	@Nullable
	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);
	}

切点信息的获取,所谓获取切点信息就是指定注解的表达式信息的获取:

@Nullable
	private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
	//获取注解上的方法
		AspectJAnnotation<?> aspectJAnnotation =
				AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
		if (aspectJAnnotation == null) {
			return null;
		}
//使用 AspectJExpressionPointcut 封装获取信息

		AspectJExpressionPointcut ajexp =
				new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
				//提取得到的注解中的表达式,如
//@Point (“execution(* * . *test*( .. ))”)中的 execution(* * . *test*( .. ))
		ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
		if (this.beanFactory != null) {
			ajexp.setBeanFactory(this.beanFactory);
		}
		return ajexp;
	}
		@Nullable
	protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
		Class<?>[] classesToLookFor = new Class<?>[] {
				Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
		for (Class<?> c : classesToLookFor) {
			AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
			if (foundAnnotation != null) {
				return foundAnnotation;
			}
		}
		return null;
	}

根据切点信息进行增强

所有的增强都由 Advisor的实现类 InstantiationModelAwarePointcutAdvisorImpl实现封装的。
org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl

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;

		if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
		//切入点的静态部分是惰性类型。
			Pointcut preInstantiationPointcut = Pointcuts.union(
					aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

		//使其动态:必须从实例化前的状态变化到实例化后的状态。
		//如果它不是动态切入点,可能会被优化出来
		//由Spring AOP基础设施进行第一次评估。
			this.pointcut = new PerTargetInstantiationModelPointcut(
					this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
			this.lazy = true;
		}
		else {
			//一个单例方面。
			this.pointcut = this.declaredPointcut;
			this.lazy = false;
			//注意这个函数instantiateAdvice
			this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
		}
	}
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
		Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
				this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
		return (advice != null ? advice : EMPTY_ADVICE);
	}

因为不同的增强所体现的逻辑是不同的,比如@Before(“ test()”)与@After (“tes ()” )标签的不同就是增强器增强的位置不同 ,所以就需要不同的增强器来完成不同的 逻辑,而根据注解中的信息初始化对应的增强器就是在instantiateAdvice函数中现的。

org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvice

    @Override
	@Nullable
	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;
		}

		//如果我们到这里,我们知道我们有一个AspectJ方法。
		//检查它是否是一个aspectj注释的类
		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()) {
			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;
			case AtAround:
				springAdvice = new AspectJAroundAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtPointcut:
				if (logger.isDebugEnabled()) {
					logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
				}
				return null;
			default:
				throw new UnsupportedOperationException(
						"Unsupported advice type on method: " + candidateAdviceMethod);
		}

		//现在配置通知…
		springAdvice.setAspectName(aspectName);
		springAdvice.setDeclarationOrder(declarationOrder);
		String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
		if (argNames != null) {
			springAdvice.setArgumentNamesFromStringArray(argNames);
		}
		springAdvice.calculateArgumentBindings();

		return springAdvice;
	}

几个增强器的介绍

  1. AspectJMethodBeforeAdvice
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {

	public AspectJMethodBeforeAdvice(
			Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {

		super(aspectJBeforeAdviceMethod, pointcut, aif);
	}


	@Override
	public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
		invokeAdviceMethod(getJoinPointMatch(), null, null);
	}

	@Override
	public boolean isBeforeAdvice() {
		return true;
	}

	@Override
	public boolean isAfterAdvice() {
		return false;
	}

}

其中的属性 MethodBeforeAdvice 表着前置增强的 AspectJMethodBeforeAdvice ,跟踪
before 方法。
org.springframework.aop.aspectj.AbstractAspectJAdvice#invokeAdviceMethod(org.aspectj.weaver.tools.JoinPointMatch, java.lang.Object, java.lang.Throwable)

protected Object invokeAdviceMethod(
			@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)
			throws Throwable {

		return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
	}
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
		Object[] actualArgs = args;
		if (this.aspectJAdviceMethod.getParameterCount() == 0) {
			actualArgs = null;
		}
		try {
			ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
			// TODO AopUtils.invokeJoinpointUsingReflection
			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();
		}
	}
  1. AspectJAfterAdvice
    请注意finally块
public class AspectJAfterAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {

	public AspectJAfterAdvice(
			Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {

		super(aspectJBeforeAdviceMethod, pointcut, aif);
	}


	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		finally {
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}

	@Override
	public boolean isBeforeAdvice() {
		return false;
	}

	@Override
	public boolean isAfterAdvice() {
		return true;
	}

}

增加同步实例化增强器

org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors
在这里插入图片描述
如果寻找的增强器不为空而且又配置了增强延迟初始化,那么就需要在首位加入同步实例
增强器。

org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor

protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor {

		public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) {
			super(aif.getAspectMetadata().getPerClausePointcut(), (MethodBeforeAdvice)
					(method, args, target) -> aif.getAspectInstance());
		}
	}

找到DeclareParents字段

	@Nullable
	private Advisor getDeclareParentsAdvisor(Field introductionField) {
		DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
		if (declareParents == null) {
			//不是介绍字段
			return null;
		}

		if (DeclareParents.class == declareParents.defaultImpl()) {
			throw new IllegalStateException("'defaultImpl' attribute must be set on DeclareParents");
		}

		return new DeclareParentsAdvisor(
				introductionField.getType(), declareParents.value(), declareParents.defaultImpl());
	}

3.3 寻找匹配的Advisors

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
在这里插入图片描述

protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
		//过滤得到匹配的advisors
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}

org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new ArrayList<>();
		//首先处理IntroductionAdvisor
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor) {
				//已经处理过的
				continue;
			}
			//对于普通bean的处理
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}
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 {
			//它没有切入点,所以我们假设它适用。
			return true;
		}
	}
	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) {
		//如果匹配任何方法,就不需要迭代方法…
			return true;
		}

		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		Set<Class<?>> classes = new LinkedHashSet<>();
		if (!Proxy.isProxyClass(targetClass)) {
			classes.add(ClassUtils.getUserClass(targetClass));
		}
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

		for (Class<?> clazz : classes) {
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				if (introductionAwareMethodMatcher != null ?
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}
		return false;
	}

3.4 创建代理

上面获取过对应的增强实例后,就可以开始进行代理的创建了。

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);
		//决定对于给定的bean是否应该使用targetclass而不是它的接口代理
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				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());
	}

具体流程如下:

  1. 获取当前类中的属性
  2. 添加代理接口
  3. 封装Advisors并加入到ProxyFactory中
  4. 设置要代理的类
  5. Spring 中还为子类提供了定制的函数 customizeProxyFactory,子类可以在此函数中进行对 ProxyFactory的进一步封装
  6. 进行获取代理操作

buildAdvisors


/*
*确定给定bean的Advisors,包括特定的拦截器
*以及常见的拦截器,都适应了Advisor接口。
*/
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
		// 解析注册的所有interceptorName
		Advisor[] commonInterceptors = resolveInterceptorNames();

		List<Object> allInterceptors = new ArrayList<>();
		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));
				}
			}
		}
		if (logger.isDebugEnabled()) {
			int nrOfCommonInterceptors = commonInterceptors.length;
			int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
			logger.debug("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
					" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
		}

		Advisor[] advisors = new Advisor[allInterceptors.size()];
		for (int i = 0; i < allInterceptors.size(); i++) {
		//拦截器转化为advisor
			advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
		}
		return advisors;
	}

org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#wrap

	@Override
	public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
	//如果要封装的对象就是Advisor类型的,那么无需再做过多的处理
		if (adviceObject instanceof Advisor) {
			return (Advisor) adviceObject;
		}
		//因为此封装方法只对Advisor与Advice两种类型的数据有效,如果不是将不能封装
		if (!(adviceObject instanceof Advice)) {
			throw new UnknownAdviceTypeException(adviceObject);
		}
		Advice advice = (Advice) adviceObject;
		if (advice instanceof MethodInterceptor) {
		//如果是方法拦截类型
			// So well-known it doesn't even need an adapter.
			return new DefaultPointcutAdvisor(advice);
		}
		for (AdvisorAdapter adapter : this.adapters) {
			// Check that it is supported.
			if (adapter.supportsAdvice(advice)) {
				return new DefaultPointcutAdvisor(advice);
			}
		}
		throw new UnknownAdviceTypeException(advice);
	}

由于Spring中涉及过滤器、拦截器、增强器、增强方法等方式来对逻辑进行增强,所以非常有必要统一封装成 so 来进行代理的创建,完成了增强的封装过程,那么解析最重要的一步就是代理的创建与获取了。

getProxy

public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy
先来看createAopProxy:

	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}

org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy

	@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);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

从这个createAopProxy方法就可以看出,Spring是如何从JDKProxy和CGLIBProxy中抉择的:
在这里插入图片描述

  • isOptimize:是否使用激进的优化策略。对jdk无效
  • isProxyTargetClass: 属性为 true时,目标类本身被代理而不是目标类接口,如果这个属性值被设为true, CGLIB 代理将被创建。也就是之前说的<aop:aspectj- Autoproxy-roxy taget-class= true/>
  • hasNoUserSuppliedProxyInterfaces:是否存在代理接口

JDK与CGLIB的选择

  • 如果目标实现了接口,默认或用JDK。
  • 如果目标实现了接口,可强制使用CGLIB。
  • 如果目标没有实现接口,必须采用CGLIB库。

如何强制添加CGLIB?

  • 类路径添加CGLIB jar包。

  • 配置文件加入在这里插入图片描述
    或者@EnableAspectJAutoProxy。

  • 该类或方法最好不要声明成final,因为CGLIB的实现是继承。


那么Spring判断出选择那种代理方式后,解析来看这两种AOPProxy的getProxy方法:

  1. org.springframework.aop.framework.JdkDynamicAopProxy
@Override
	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);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

由于,JdkDynamicAopProxy实现了InvocationHandler接口,那么知道jdk动态代理怎么使用的应该知道,重要的方法在invoke:

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
	@Override
	@Nullable
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation;
		Object oldProxy = null;
		boolean setProxyContext = false;

		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
		//equals方法的处理
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				//目标本身没有实现equals(Object)方法。
				return equals(args[0]);
			}
			//hash方法的处理
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
			//目标本身没有实现hashCode()方法。
				return hashCode();
			}
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
			//只有getDecoratedClass()声明->分派到代理配置。
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			//Class类的isAssignableFrom方法
			//如果调用这个方法的class或者接口与参数表示的类相同则为true
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
			//代理配置对ProxyConfig的服务调用…
				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()) {
			//我们可以跳过创建方法调用:直接调用目标
			//注意,最后的调用程序必须是一个InvokerInterceptor,所以我们知道它是这样的
			//只是目标上的一个反射操作,没有热交换或花哨的代理。
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
			//我们需要创建一个方法调用…
				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())) {
			//特殊情况:返回“this”和方法的返回类型
			//是兼容的。注意,如果目标设置了,我们就无能为力了
			//在另一个返回对象中对自身的引用。
				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()) {
			//必须来自TargetSource。
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				//恢复旧代理。
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

以上方法主要工作创建了一个拦截器链,并使用ReflectiveMethodInvocation进行链的封装,其重要方法就是:

	retVal = invocation.proceed();

org.springframework.aop.framework.ReflectiveMethodInvocation#proceed

@Override
	@Nullable
	public Object proceed() throws Throwable {
		// 执行完所有增强后执行切点方法
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}
		//获取下一个要执行的拦截器
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			//动态匹配
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				//不匹配则不执行拦截器
				return proceed();
			}
		}
		else {
		//它是一个拦截器,所以我们只需调用它:切入点将会有
		//在构造此对象之前被静态计算。
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

里面存在递归调用,该方法主要是维护了当前链调用的索引位置。工作委托给各个增强器。

  1. org.springframework.aop.framework.CglibAopProxy

先来看CGLIB的使用实例:


public class SampleClass {
    public void test(){
        System.out.println("hello world");
    }
 
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(SampleClass.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("before method run...");
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("after method run...");
                return result;
            }
        });
        SampleClass sample = (SampleClass) enhancer.create();
        sample.test();
    }
}
@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
		}

		try {
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

			Class<?> proxySuperClass = rootClass;
			if (ClassUtils.isCglibProxyClass(rootClass)) {
				proxySuperClass = rootClass.getSuperclass();
				Class<?>[] additionalInterfaces = rootClass.getInterfaces();
				for (Class<?> additionalInterface : additionalInterfaces) {
					this.advised.addInterface(additionalInterface);
				}
			}

			//验证类,根据需要写入日志消息。
			validateClassIfNecessary(proxySuperClass, classLoader);

			//配置CGLIB增强器…
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			enhancer.setSuperclass(proxySuperClass);
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

			Callback[] callbacks = getCallbacks(rootClass);
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			// fixedInterceptorMap仅在此填充,在上面的getCallbacks调用之后
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			enhancer.setCallbackTypes(types);

			//生成代理类并创建代理实例。
			return createProxyClassAndInstance(enhancer, callbacks);
		}
		catch (CodeGenerationException | IllegalArgumentException ex) {
			throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
					": Common causes of this problem include using a final class or a non-visible class",
					ex);
		}
		catch (Throwable ex) {
		// TargetSource.getTarget()失败
			throw new AopConfigException("Unexpected AOP exception", ex);
		}
	}

上面的方法主要完成了Enhancer的创建,重要的是getCallbacks方法:

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
		//用于优化选择的参数…
		boolean exposeProxy = this.advised.isExposeProxy();
		boolean isFrozen = this.advised.isFrozen();
		boolean isStatic = this.advised.getTargetSource().isStatic();

		//选择一个“aop”拦截器(用于aop调用)。
		Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

		//选择一个“直击目标”的拦截器。(用于呼叫
		//不建议,但可以返回这个)。可能需要公开代理。
		Callback targetInterceptor;
		if (exposeProxy) {
			targetInterceptor = (isStatic ?
					new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
		}
		else {
			targetInterceptor = (isStatic ?
					new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
		}

		//选择一个“直接到目标”分派器(用于
		//对无法返回此值的静态目标的未建议调用)。
		Callback targetDispatcher = (isStatic ?
				new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

		Callback[] mainCallbacks = new Callback[] {
				aopInterceptor, //征求一般意见
				targetInterceptor, //调用目标,而不考虑通知,如果优化
				new SerializableNoOp(), //没有覆盖映射到此的方法
				targetDispatcher, this.advisedDispatcher,
				new EqualsInterceptor(this.advised),
				new HashCodeInterceptor(this.advised)
		};

		Callback[] callbacks;

		//如果目标是静态的,通知链被冻结,
		//然后我们可以通过发送AOP调用来进行一些优化
		//对该方法使用固定链直接指向目标。
		if (isStatic && isFrozen) {
			Method[] methods = rootClass.getMethods();
			Callback[] fixedCallbacks = new Callback[methods.length];
			this.fixedInterceptorMap = new HashMap<>(methods.length);

			// TODO:小内存优化(可以跳过没有建议的方法的创建)
			for (int x = 0; x < methods.length; x++) {
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
				fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
						chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
				this.fixedInterceptorMap.put(methods[x].toString(), x);
			}

			//现在从mainCallbacks中复制两个回调
			//和fixedCallbacks到回调数组中。
			callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
			System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
			System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
			this.fixedInterceptorOffset = mainCallbacks.length;
		}
		else {
			callbacks = mainCallbacks;
		}
		return callbacks;
	}

CGLIB 中对于方法的拦截是通过将自定义的拦截器(实现 Methodlnterceptor 接口)加入Callback 中并在调用代理时直接激活拦截器中的 intercept 方法来实现的,那么在getCallback 中正是实现了这样目的, DynamicAdvisedlnterceptor 继承自Methodlnterceptor ,加 callback 后,在再次调用代理会直接用DynamicAvisedlnterceptor 中的 intercept 方法,由此推断,对于 CGLIB 方式实现的代理,其核心逻辑必然在 DynamicAdvisedlnterceptor 中的 intercept中。

总结:首先构造链,然后封装此链进行串联调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值