源码1
1.@EnableCaching注解,Import导入CachingConfigurationSelector,导入的类是AutoProxyRegistrar和ProxyCachingConfiguration
private String[] getProxyImports() { List<String> result = new ArrayList<String>(); result.add(AutoProxyRegistrar.class.getName()); result.add(ProxyCachingConfiguration.class.getName()); if (jsr107Present && jcacheImplPresent) { result.add(PROXY_JCACHE_CONFIGURATION_CLASS); } return result.toArray(new String[result.size()]); }
源码2
AutoProxyRegistrar是ImportBeanDefinitionRegistrar的实现类,关键是注册InfrastructureAdvisorAutoProxyCreator
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean candidateFound = false; Set<String> annoTypes = importingClassMetadata.getAnnotationTypes(); for (String annoType : annoTypes) { 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; if (mode == AdviceMode.PROXY) { //关键点:注册InfrastructureAdvisorAutoProxyCreator到IOC容器 AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry); if ((Boolean) proxyTargetClass) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); return; } } } } } public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source); } private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { 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; }
源码3
InfrastructureAdvisorAutoProxyCreator是BeanPostProcessor的实现,也就所有的Bean的实例化&初始化生命周期过程中可以进行加上自定义的逻辑,可以从抽象父类AbstractAutoProxyCreator看生命周期的处理过程中postProcessAfterInitialization方法,
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //找到与bean符合的advisor,看AbstractAdvisorAutoProxyCreator Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //如果找到合适的Advisor会创建相应的代理类 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; } @Override protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) { List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); } protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { //找到IOC所有的Advisor类型的 List<Advisor> candidateAdvisors = findCandidateAdvisors(); //遍历Advisor并通过pointCut找出能与bean匹配的Advisor List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; } public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new LinkedList<Advisor>(); 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) { // already processed continue; } //缓存的Advisor是BeanFactoryCacheOperationSourceAdvisor,且是PointCutAdvisor的实现,执行到这里 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) { //获取BeanFactoryCacheOperationSourceAdviso的CacheOperationSourcePointcut进行拦截 PointcutAdvisor pca = (PointcutAdvisor) advisor; return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { // It doesn't have a pointcut so we assume it applies. return true; } } public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { //CacheOperationSourcePointcut是MethodMatcher实现,找到bean所有方法进行匹配拦截 for (Class<?> clazz : classes) { Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); for (Method method : methods) { if ((introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) || //直接看CacheOperationSourcePointcut的matches methodMatcher.matches(method, targetClass)) { return true; } } } return false; }
源码4
ProxyCachingConfiguration配置BeanFactoryCacheOperationSourceAdvisor到IOC容器
@Bean(name = CacheManagementConfigUtils.CACHE_ADVISOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public BeanFactoryCacheOperationSourceAdvisor cacheAdvisor() { //是一个PointcutAdvisor的实现,Pointcut为CacheOperationSourcePointcut和Advice为CacheInterceptor BeanFactoryCacheOperationSourceAdvisor advisor = new BeanFactoryCacheOperationSourceAdvisor(); //用于扫描缓存相关注解 advisor.setCacheOperationSource(cacheOperationSource()); //CacheInterceptor是MethodInterceptor、InitializingBean的实现 advisor.setAdvice(cacheInterceptor()); advisor.setOrder(this.enableCaching.<Integer>getNumber("order")); return advisor; }
源码5
CacheOperationSourcePointcut是一个MethodMatcher匹配拦截的Pointcut,注意是查找类的方法是否有缓存相关注解,找到则匹配通过,直接关注matchs方法
@Override public boolean matches(Method method, Class<?> targetClass) { //这里CAS是AnnotationCacheOperationSource CacheOperationSource cas = getCacheOperationSource(); return (cas != null && !CollectionUtils.isEmpty(cas.getCacheOperations(method, targetClass))); } @Override public Collection<CacheOperation> getCacheOperations(Method method, Class<?> targetClass) { if (method.getDeclaringClass() == Object.class) { return null; } Object cacheKey = getCacheKey(method, targetClass); Collection<CacheOperation> cached = this.attributeCache.get(cacheKey); if (cached != null) { return (cached != NULL_CACHING_ATTRIBUTE ? cached : null); } else { //查找缓存注解 Collection<CacheOperation> cacheOps = computeCacheOperations(method, targetClass); if (cacheOps != null) { if (logger.isDebugEnabled()) { logger.debug("Adding cacheable method '" + method.getName() + "' with attribute: " + cacheOps); } this.attributeCache.put(cacheKey, cacheOps); } else { this.attributeCache.put(cacheKey, NULL_CACHING_ATTRIBUTE); } return cacheOps; } } private Collection<CacheOperation> computeCacheOperations(Method method, Class<?> targetClass) { specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); // 先查找方法上是否有缓存注解 Collection<CacheOperation> opDef = findCacheOperations(specificMethod); if (opDef != null) { return opDef; } // 先查找类上是否有缓存注解 opDef = findCacheOperations(specificMethod.getDeclaringClass()); if (opDef != null && ClassUtils.isUserLevelMethod(method)) { return opDef; } return null; }
源码6
CacheInterceptor是MethodInterceptor实现,代理类执行的时候会调用(关注AOP的责任链调用),并且是SmartInitializingSingleton实现(关注afterSingletonsInstantiated方法)
@Override public void afterSingletonsInstantiated() { if (getCacheResolver() == null) { try { //从IOC容器获取CacheManager,这个我们一般会自己配置 setCacheManager(this.beanFactory.getBean(CacheManager.class)); } catch (NoUniqueBeanDefinitionException ex) { } } this.initialized = true; } @Override public Object invoke(final MethodInvocation invocation) throws Throwable { //Aop拦截的时候执行到这里 Method method = invocation.getMethod(); CacheOperationInvoker aopAllianceInvoker = new CacheOperationInvoker() { @Override public Object invoke() { try { //缓存未命中的时候会执行 return invocation.proceed(); } catch (Throwable ex) { throw new ThrowableWrapper(ex); } } }; try { return execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments()); } catch (CacheOperationInvoker.ThrowableWrapper th) { throw th.getOriginal(); } } private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) { // 处理CacheEvict注解 processCacheEvicts(contexts.get(CacheEvictOperation.class), true, CacheOperationExpressionEvaluator.NO_RESULT); // 处理Cacheable注解,查找缓存值 Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class)); // Collect puts from any @Cacheable miss, if no cached item is found List<CachePutRequest> cachePutRequests = new LinkedList<CachePutRequest>(); if (cacheHit == null) { //未命中添加CachePutRequest,用于业务执行后返回值不为空添加到缓存 collectPutRequests(contexts.get(CacheableOperation.class), CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests); } Object cacheValue; Object returnValue; if (cacheHit != null && cachePutRequests.isEmpty() && !hasCachePut(contexts)) { // 缓存命中直接返回,不会再进行AOP的责任链进行执行了,也就不会执行到业务逻辑了 cacheValue = cacheHit.get(); returnValue = wrapCacheValue(method, cacheValue); } else { // 缓存未命中,并继续按照AOP责任链执行,最后会执行到业务逻辑 returnValue = invokeOperation(invoker); cacheValue = unwrapReturnValue(returnValue); } //// 处理CachePuts注解,查找缓存值 collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests); //执行缓存未命中的时候添加的CachePutRequest for (CachePutRequest cachePutRequest : cachePutRequests) { cachePutRequest.apply(cacheValue); } // Process any late evictions processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue); return returnValue; }