001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.cache.annotation; 018 019import java.util.ArrayList; 020import java.util.List; 021 022import org.springframework.context.annotation.AdviceMode; 023import org.springframework.context.annotation.AdviceModeImportSelector; 024import org.springframework.context.annotation.AutoProxyRegistrar; 025import org.springframework.util.ClassUtils; 026import org.springframework.util.StringUtils; 027 028/** 029 * Selects which implementation of {@link AbstractCachingConfiguration} should 030 * be used based on the value of {@link EnableCaching#mode} on the importing 031 * {@code @Configuration} class. 032 * 033 * <p>Detects the presence of JSR-107 and enables JCache support accordingly. 034 * 035 * @author Chris Beams 036 * @author Stephane Nicoll 037 * @since 3.1 038 * @see EnableCaching 039 * @see ProxyCachingConfiguration 040 */ 041public class CachingConfigurationSelector extends AdviceModeImportSelector<EnableCaching> { 042 043 private static final String PROXY_JCACHE_CONFIGURATION_CLASS = 044 "org.springframework.cache.jcache.config.ProxyJCacheConfiguration"; 045 046 private static final String CACHE_ASPECT_CONFIGURATION_CLASS_NAME = 047 "org.springframework.cache.aspectj.AspectJCachingConfiguration"; 048 049 private static final String JCACHE_ASPECT_CONFIGURATION_CLASS_NAME = 050 "org.springframework.cache.aspectj.AspectJJCacheConfiguration"; 051 052 053 private static final boolean jsr107Present; 054 055 private static final boolean jcacheImplPresent; 056 057 static { 058 ClassLoader classLoader = CachingConfigurationSelector.class.getClassLoader(); 059 jsr107Present = ClassUtils.isPresent("javax.cache.Cache", classLoader); 060 jcacheImplPresent = ClassUtils.isPresent(PROXY_JCACHE_CONFIGURATION_CLASS, classLoader); 061 } 062 063 064 /** 065 * Returns {@link ProxyCachingConfiguration} or {@code AspectJCachingConfiguration} 066 * for {@code PROXY} and {@code ASPECTJ} values of {@link EnableCaching#mode()}, 067 * respectively. Potentially includes corresponding JCache configuration as well. 068 */ 069 @Override 070 public String[] selectImports(AdviceMode adviceMode) { 071 switch (adviceMode) { 072 case PROXY: 073 return getProxyImports(); 074 case ASPECTJ: 075 return getAspectJImports(); 076 default: 077 return null; 078 } 079 } 080 081 /** 082 * Return the imports to use if the {@link AdviceMode} is set to {@link AdviceMode#PROXY}. 083 * <p>Take care of adding the necessary JSR-107 import if it is available. 084 */ 085 private String[] getProxyImports() { 086 List<String> result = new ArrayList<>(3); 087 result.add(AutoProxyRegistrar.class.getName()); 088 result.add(ProxyCachingConfiguration.class.getName()); 089 if (jsr107Present && jcacheImplPresent) { 090 result.add(PROXY_JCACHE_CONFIGURATION_CLASS); 091 } 092 return StringUtils.toStringArray(result); 093 } 094 095 /** 096 * Return the imports to use if the {@link AdviceMode} is set to {@link AdviceMode#ASPECTJ}. 097 * <p>Take care of adding the necessary JSR-107 import if it is available. 098 */ 099 private String[] getAspectJImports() { 100 List<String> result = new ArrayList<>(2); 101 result.add(CACHE_ASPECT_CONFIGURATION_CLASS_NAME); 102 if (jsr107Present && jcacheImplPresent) { 103 result.add(JCACHE_ASPECT_CONFIGURATION_CLASS_NAME); 104 } 105 return StringUtils.toStringArray(result); 106 } 107 108}