Spring AOP常用概念以及自动代理实现原理剖析

392 阅读9分钟

Spring AOP

核心组件概念以及作用

  • JoinPoint : 连接点,在Spring AOP中指代调用方法,核心实现有MethodInvocation、ReflectiveMethodInvocation
  • Pointcut : 切入点,在Spring AOP中指代对具体的连接点的过滤,比如Spring中的ClassFilter/MethodMatcher
  • Advice : 通知,就是具体的增强代码,有前置后置,环绕等.. , 核心实现为MethodInterceptor
  • Aspect :是包含上面组件的类(Spring AOP)中。
  • Advisor : 是Advice的容器,其中可以获取通知类,一般实现有两种PointcutAdvisor/IntroductionAdvisor,前者提供PointCut过滤,后者提供ClassFilter过滤
  • AopProxy : 表示Aop代理对象,提供getProxy()来获取代理对象,有动态代理Cglib字节码提升两种实现方式
  • AopProxyFactory : Aop代理工厂,通过传入AdvisedSupport配置信息来创建AopProxy对象,默认实现为DefaultAopProxyFactory
  • AdvisedSupport : 扩展了ProxyConfig类,提供了目标源对象TargetSource的管理和所有Advisor通知类,以及进行Advice到MethodInterceptor适配工作的AdvisorChainFactory
  • AdvisorAdaptor/AdvisorAdaptorRegistryAdvisorChainFactory通过AdvisorAdaptoyRegistry注册的AdvisorAdaptorAdvisor适配成MethodInterceptor
  • AbstractAutoProxyCreator : 自动代理类,实现了SmartInstantiationAwareBeanPostProcessor,在postProcessBeforeInstantiation()/postProcessAfterInitialization()进行代理拦截,并且通过依赖查找来打通AOP和IOC

自动代理实现原理

通常我们在代码中使用AOP的方式都是整合了IOC的自动代理模式,即AutoProxyCreator这个抽象实现,重点聚焦于AnnotationAwareAspectJAutoProxyCreator,这也是@EnableAspectJAutoProxy的原理

  1. AnnotationAwareAspectJAutoProxyCreatorSmartInstantiationAwareBeanPostProcessor的实现类 , 所以观察可知,在Bean的实例化以及初始化前后会有一定增强。目光聚焦到postProcessAfterInitialization()
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
      		//1. 查看是否命中缓存
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
      		//2. 若之前的缓存和现在的bean不同,则进行增强
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
      			 //3. 增强方法
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
  1. 继续来跟进wrapIfNecessary(bean,beanName,cacheKey)
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		//1. 命中缓存直接返回
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		//2. 相关切面相关类也直接返回
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		//3. 判断是否是切面相关类型 shouldSkip -> 会获取获取切面并解析成Advisor
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		// 获取Advisor/Advice
		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;
	}

​ 2.1 其中重要的两个步骤

  • 获取所有的Advisor
//核心代理,获取所有的Advisor/切面 Bean
 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

	//AbstractAdvisorAutoProxyCreator
	@Override
	@Nullable
	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
		/*查询所有有效的Advisor*/
		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) {
		/*1. 在IOC中查找Advisor相关Bean以及切面Bean*/
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		/*2. 过滤获取需要拦截beanClass的Advisor*/
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		/*3. AspectJ扩展候选的Advisor*/
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			/*4. 进行Order排序*/
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}
  • 创建代理对象
	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
		/*1. 在BeanDefinition中存储Target Class引用*/
		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this); /*AbstractAutoProxyCreator本来也是ProxyConfig的子类*/
		//判断是否需要使用CGLIB
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				//从是否有接口判断
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		// 获取合并后的Advisor (手动添加的InterceptorNames + Advisor + AspectJ注解方法(AspectJ 注解环境下))
		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. 当创建代理对象后,调用代理对象的方法会回调到JdkDynamicAopProxy#invoke()方法,原因是创建代理对象的时候将相关的AopProxy实现当做InvocationHandler/MethodInterceptor

    3.1 基于接口的代理 : JdkDynamicAopProxy#invoke()

    3.2 基于类的代理CglibAopProxy$DynamicAdvisedInterceptor#intercept()方法

//用Jdk动态代理作为示例,下面截取了invoke()的核心步骤
// JdkDynamicAopProxy#invoke() 

			/*若开启了exposeProxy = true则将代理对象设置到AopContext的ThreadLocal中*/
			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			target = targetSource.getTarget();
			Class<?> targetClass = (target != null ? target.getClass() : null);
			/*委派给AdvisorChainFactory将所有的Advisor适配成MethodInterceptor*/
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// Check whether we have any advice. If we don't, we can fallback on direct
			// reflective invocation of the target, and avoid creating a MethodInvocation.
			/*若没有通知拦截对象,则直接进行目标连接点反射调用*/
			if (chain.isEmpty()) {
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				/*封装成ReflectiveMethodInvocation进行代理调用*/
				MethodInvocation invocation =
						new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
       //执行JoinPoint的方法
				retVal = invocation.proceed();
			}

ReflectiveMethodInvocation#proceed()

	public Object proceed() throws Throwable {
		// We start with an index of -1 and increment early.
		/*1. 若当前责任链索引游标等于所有通知类size-1则直接调用目标方法 (到达了最后一个MethodInterceptor拦截)*/
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}
		/*2. 获取最后一个MethodInterceptor*/
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		/*3. 处理InterceptorAndDynamicMethodMatcher类型的MethodInterceptor,先进行MethodMatcher匹配 (AspectJ #DeclareParents)*/
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
			if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				return proceed();
			}
		}
		else {
			/*4. 一般都会到这一步,执行当前责任链索引对应的MethodInterceptor#invoke方法*/
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

几种常见MethodInterceptor的实现

  • 前置
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
	private final MethodBeforeAdvice advice;

	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}
	public Object invoke(MethodInvocation mi) throws Throwable {
    //在目标方法调用执行,执行before
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		return mi.proceed();
	}
}
  • 后置
public class AspectJAfterAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {

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

		super(aspectJBeforeAdviceMethod, pointcut, aif);
	}
	@Override
	@Nullable
	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;
	}
}
  • 环绕
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {

	public AspectJAroundAdvice(
			Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {

		super(aspectJAroundAdviceMethod, pointcut, aif);
	}
	@Override
	@Nullable
	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);
    //调用Aspect @Around标记的方法,然后通过ProceedJoinPoint来回调目标方法
		return invokeAdviceMethod(pjp, jpm, null, null);
	}

Spring AOP应用整合场景之SpringTX

核心观察Spring如何使用AOP来整合事务,重点观察@EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//导入了一个Configuration Class
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
  //是否使用基于类的代理
	boolean proxyTargetClass() default false;
  //代理的模式
	AdviceMode mode() default AdviceMode.PROXY;
  //代理类的序号
	int order() default Ordered.LOWEST_PRECEDENCE;
}

查看TransactionManagenetConfiurationSelector,是一个ImportSelector的实现,该类实现都是通过ConfigurationClassPostProcessor来回调从而向IOC添加单实例Bean

public class TransactionManagementConfigurationSelector extends 
  //1. AdviceModeImportSelector是类似模板方法,作用是读取@EnableXX注解上的注解元信息并将AdviceMode传递给子类
  AdviceModeImportSelector<EnableTransactionManagement> {
	
  //2. 根据用户设置的通知模式(Proxy/AspectJ)来进行注入相关的Bean
	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(),
						ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {determineTransactionAspectClass()};
			default:
				return null;
		}
	}

	private String determineTransactionAspectClass() {
		return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
				TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
				TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
	}

}

AutoProxyRegistrar

自动代理类的注册类 , 实现了ImportBeanDefinitionRegistrar,通过registerBeanDefinitions()注入Bean

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
    //1. 获取导入类的注解类型 (@EnableXXX)
		Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
		for (String annType : annTypes) {
      //2. 获取属性元信息
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
			if (candidate == null) {
				continue;
			}
			//3. 获取对应的属性值
			Object mode = candidate.get("mode");
			Object proxyTargetClass = candidate.get("proxyTargetClass");
			if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
					Boolean.class == proxyTargetClass.getClass()) {
				candidateFound = true;
        //4. 使用AopConfigUtils注册AutoProxyCreater自动代理类到IOC中
				if (mode == AdviceMode.PROXY) {
					/*1. 注册InfrastructureAdvisorAutoProxyCreator自动代理类到IOC中*/
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
					if ((Boolean) proxyTargetClass) {
						/*2. 设置CGLIB代理*/
						AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
						return;
					}
				}
			}
		}
  }
}

ProxyTransactionManagementConfiguration

这个类是事务功能的相关配置类 ,其中主要添加了如下组件到IOC中

  • TransactionAttributeSource : 读取方法或者类上的@Transactional注解的类

  • TransactionInterceptor : 拦截事务的主要通知类

  • BeanFactoryTransactionAttributeSourceAdvisor : 事务的相关Advisor类,其中说明只针对@Transactional注解的方法/类进行拦截(Pointcut机制)

  • TransactionalEventListenerFactory : 事务的监听器机制@TransactionalEventListener,可以方便我们在事务的提交前后执行监听业务的执行

  • TransactionManagementConfigurer : 事务管理扩展配置类,可以通过添加该类到IOC中来对TransactionManager进行自定义

BeanFactoryTransactionAttributeSourceAdvisor源码

Advisor主要有两部分组成,一个是Advice通知类 ,这里为TransactionInterceptor,一个是过滤,这里是TransactionAttributeSourcePointcut

  • TransactionAttributeSourcePointcut : 通过判断是否有@Transcational元信息
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {

	protected TransactionAttributeSourcePointcut() {
		setClassFilter(new TransactionAttributeSourceClassFilter());
	}
	@Override
	public boolean matches(Method method, Class<?> targetClass) {
		TransactionAttributeSource tas = getTransactionAttributeSource();
    //通过TransactionAttributesSource判断当前方法/类上是否有@Transactional注解
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}
}
  • TransactionInterceptor :aop通知拦截
	//TransactionInterceptor#invoke()
@Override
	@Nullable
	public Object invoke(MethodInvocation invocation) throws Throwable {
    //1. 获取目标Class
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
		//2. kotlin调用
		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		if (KotlinDetector.isSuspendingFunction(invocation.getMethod())) {
			InvocationCallback callback = new CoroutinesInvocationCallback() {
				@Override
				public Object proceedWithInvocation() {
					return CoroutinesUtils.invokeSuspendingFunction(invocation.getMethod(), invocation.getThis(), invocation.getArguments());
				}
				@Override
				public Object getContinuation() {
					return invocation.getArguments()[invocation.getArguments().length - 1];
				}
			};
			return invokeWithinTransaction(invocation.getMethod(), targetClass, callback);
		} 
    //3.  主要会进入这里,传入目标方法的调用Supplier
    /*调用父类执行事务*/
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	}

invokeWithinTransaction()

	protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		TransactionAttributeSource tas = getTransactionAttributeSource(); /*1. normally that is AnnotationTransactionAttributeSource*/
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null); /*2. 尝试获取TransactionAttributes*/
		final TransactionManager tm = determineTransactionManager(txAttr); /*3. 查找对应的事务管理器*/
		/*4. 省略Reactive Programing 事务支持*/
		//...
		/*5. 转化成PlatformTransactionManager*/
		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
		/*6. 获取连接点方法描述*/
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
		/*7. 一般会进入这个分支(除了WebSphere和Test模块的Mock)*/
		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			/*7.1 根据不同的传播特性来跳过创建事务,创建新事务,嵌套事务等..并返回事务信息*/
			TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

			Object retVal;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				/*7.2 执行目标方法*/
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				cleanupTransactionInfo(txInfo);
			}

			if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
				// Set rollback-only in case of Vavr failure matching our rollback rules...
				TransactionStatus status = txInfo.getTransactionStatus();
				if (status != null && txAttr != null) {
					retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
				}
			}
			/*Commit事务*/
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

总结

  1. 通过@EnableTransactionManagement导入相关的Advisor拦截和TransactionAttributeSource属性元数据解析器

SpringAOP整合场景之Spring Caching

Spring Caching和事务的整合基本类似,下面直接总结核心组件和步骤

  • AutoProxyRegistrar : 导入自动代理类
  • CachingConfigurer :定制配置类
  • ProxyCachingConfiguration : 核心配置类
  • BeanFactoryCacheOperationSourceAdvisorCacheInterceptor : 代理拦截类
  • CacheOperationSource : 属性解析类

核心拦截步骤

//CacheAspectSupport#execute()
private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
  	//特殊处理,@Cachable(sync=true),这种方式只会处理这一个注解
		// Special handling of synchronized invocation
		if (contexts.isSynchronized()) {
			CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();
			if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {
				Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
				Cache cache = context.getCaches().iterator().next();
				try {
					return wrapCacheValue(method, handleSynchronizedGet(invoker, key, cache));
				}
				catch (Cache.ValueRetrievalException ex) {
					// Directly propagate ThrowableWrapper from the invoker,
					// or potentially also an IllegalArgumentException etc.
					ReflectionUtils.rethrowRuntimeException(ex.getCause());
				}
			}
			else {
				// No caching required, only call the underlying method
				return invokeOperation(invoker);
			}
		}


		// Process any early evictions
		/*1. CacheEvict执行(通过@CacheEvict#beforeInvocation=true)来控制在方法调用之前执行清除缓存,这是可以无视目标方法调用是否抛出异常都清除缓存,默认false*/
		processCacheEvicts(contexts.get(CacheEvictOperation.class), true,
				CacheOperationExpressionEvaluator.NO_RESULT);

		// Check if we have a cached item matching the conditions
		/*2. 获取缓存*/
		Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));

		// Collect puts from any @Cacheable miss, if no cached item is found
		List<CachePutRequest> cachePutRequests = new ArrayList<>();
		/*3. 缓存中没有对应的key*/
		if (cacheHit == null) {
			/*4. 收集缓存更新*/
			collectPutRequests(contexts.get(CacheableOperation.class),
					CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
		}

		Object cacheValue;
		Object returnValue;
		/*5. 若有缓存,且没有缓存更新,则返回缓存*/
		if (cacheHit != null && !hasCachePut(contexts)) {
			// If there are no put requests, just use the cache hit
			cacheValue = cacheHit.get();
			returnValue = wrapCacheValue(method, cacheValue);
		}
		/*6. 否则则执行目标方法*/
		else {
			// Invoke the method if we don't have a cache hit
			returnValue = invokeOperation(invoker);
			cacheValue = unwrapReturnValue(returnValue);
		}
		/*7. 再次收集缓存更新操作*/
		// Collect any explicit @CachePuts
		collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);

		// Process any collected put requests, either from @CachePut or a @Cacheable miss
		for (CachePutRequest cachePutRequest : cachePutRequests) {
			/*8. 执行put*/
			cachePutRequest.apply(cacheValue);
		}
		/*9. 最后执行清除*/
		// Process any late evictions
		processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);

		return returnValue;
	}
  • 若开启了@Cacheable(sync=true)则只单独处理这一个注解
  • 若@CacheEvict(beforeInvocation=true)则先清除缓存
  • 尝试从缓存中获取缓存
    • 若有缓存且没有@Cacheput操作,则直接返回
    • 否则则调用目标方法,将结果存入缓存中
  • 清除缓存(如果有@CacheEvict(beforeInvocation=false)的话)