美文网首页
Spring缓存源码分析

Spring缓存源码分析

作者: 一苇以航1026 | 来源:发表于2020-03-15 21:58 被阅读0次
    image.png

    源码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;
      }
    

    相关文章

      网友评论

          本文标题:Spring缓存源码分析

          本文链接:https://www.haomeiwen.com/subject/dbciehtx.html