content: /**
   * Created on  13-09-18 20:33
   */
  package com.alicp.jetcache.anno.aop;
  
  import com.alicp.jetcache.CacheManager;
  import com.alicp.jetcache.anno.method.CacheHandler;
  import com.alicp.jetcache.anno.method.CacheInvokeConfig;
  import com.alicp.jetcache.anno.method.CacheInvokeContext;
  import com.alicp.jetcache.anno.support.ConfigMap;
  import com.alicp.jetcache.anno.support.ConfigProvider;
  import com.alicp.jetcache.anno.support.GlobalCacheConfig;
  import org.aopalliance.intercept.MethodInterceptor;
  import org.aopalliance.intercept.MethodInvocation;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.beans.BeansException;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.ApplicationContext;
  import org.springframework.context.ApplicationContextAware;
  
  import java.lang.reflect.Method;
  
  /**
   * @author huangli
   */
  public class JetCacheInterceptor implements MethodInterceptor, ApplicationContextAware {
  
      private static final Logger logger = LoggerFactory.getLogger(JetCacheInterceptor.class);
  
      @Autowired
      private ConfigMap cacheConfigMap;
      private ApplicationContext applicationContext;
      private GlobalCacheConfig globalCacheConfig;
      ConfigProvider configProvider;
      CacheManager cacheManager;
  
      @Override
      public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
          this.applicationContext = applicationContext;
      }
  
      @Override
      public Object invoke(final MethodInvocation invocation) throws Throwable {
          if (configProvider == null) {
              configProvider = applicationContext.getBean(ConfigProvider.class);
          }
          if (configProvider != null && globalCacheConfig == null) {
              globalCacheConfig = configProvider.getGlobalCacheConfig();
          }
          if (globalCacheConfig == null || !globalCacheConfig.isEnableMethodCache()) {
              return invocation.proceed();
          }
          if (cacheManager == null) {
              cacheManager = applicationContext.getBean(CacheManager.class);
              if (cacheManager == null) {
                  logger.error("There is no cache manager instance in spring context");
                  return invocation.proceed();
              }
          }
  
          Method method = invocation.getMethod();
          Object obj = invocation.getThis();
          CacheInvokeConfig cac = null;
          if (obj != null) {
              String key = CachePointcut.getKey(method, obj.getClass());
              cac  = cacheConfigMap.getByMethodInfo(key);
          }
  
          /*
          if(logger.isTraceEnabled()){
              logger.trace("JetCacheInterceptor invoke. foundJetCacheConfig={}, method={}.{}(), targetClass={}",
                      cac != null,
                      method.getDeclaringClass().getName(),
                      method.getName(),
                      invocation.getThis() == null ? null : invocation.getThis().getClass().getName());
          }
          */
  
          if (cac == null || cac == CacheInvokeConfig.getNoCacheInvokeConfigInstance()) {
              return invocation.proceed();
          }
  
          CacheInvokeContext context = configProvider.newContext(cacheManager).createCacheInvokeContext(cacheConfigMap);
          context.setTargetObject(invocation.getThis());
          context.setInvoker(invocation::proceed);
          context.setMethod(method);
          context.setArgs(invocation.getArguments());
          context.setCacheInvokeConfig(cac);
          context.setHiddenPackages(globalCacheConfig.getHiddenPackages());
          return CacheHandler.invoke(context);
      }
  
      public void setCacheConfigMap(ConfigMap cacheConfigMap) {
          this.cacheConfigMap = cacheConfigMap;
      }
  
  }
  