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.Collection; 020import java.util.function.Supplier; 021 022import org.springframework.beans.factory.annotation.Autowired; 023import org.springframework.cache.CacheManager; 024import org.springframework.cache.interceptor.CacheErrorHandler; 025import org.springframework.cache.interceptor.CacheResolver; 026import org.springframework.cache.interceptor.KeyGenerator; 027import org.springframework.context.annotation.Configuration; 028import org.springframework.context.annotation.ImportAware; 029import org.springframework.core.annotation.AnnotationAttributes; 030import org.springframework.core.type.AnnotationMetadata; 031import org.springframework.lang.Nullable; 032import org.springframework.util.CollectionUtils; 033 034/** 035 * Abstract base {@code @Configuration} class providing common structure 036 * for enabling Spring's annotation-driven cache management capability. 037 * 038 * @author Chris Beams 039 * @author Stephane Nicoll 040 * @author Juergen Hoeller 041 * @since 3.1 042 * @see EnableCaching 043 */ 044@Configuration 045public abstract class AbstractCachingConfiguration implements ImportAware { 046 047 @Nullable 048 protected AnnotationAttributes enableCaching; 049 050 @Nullable 051 protected Supplier<CacheManager> cacheManager; 052 053 @Nullable 054 protected Supplier<CacheResolver> cacheResolver; 055 056 @Nullable 057 protected Supplier<KeyGenerator> keyGenerator; 058 059 @Nullable 060 protected Supplier<CacheErrorHandler> errorHandler; 061 062 063 @Override 064 public void setImportMetadata(AnnotationMetadata importMetadata) { 065 this.enableCaching = AnnotationAttributes.fromMap( 066 importMetadata.getAnnotationAttributes(EnableCaching.class.getName(), false)); 067 if (this.enableCaching == null) { 068 throw new IllegalArgumentException( 069 "@EnableCaching is not present on importing class " + importMetadata.getClassName()); 070 } 071 } 072 073 @Autowired(required = false) 074 void setConfigurers(Collection<CachingConfigurer> configurers) { 075 if (CollectionUtils.isEmpty(configurers)) { 076 return; 077 } 078 if (configurers.size() > 1) { 079 throw new IllegalStateException(configurers.size() + " implementations of " + 080 "CachingConfigurer were found when only 1 was expected. " + 081 "Refactor the configuration such that CachingConfigurer is " + 082 "implemented only once or not at all."); 083 } 084 CachingConfigurer configurer = configurers.iterator().next(); 085 useCachingConfigurer(configurer); 086 } 087 088 /** 089 * Extract the configuration from the nominated {@link CachingConfigurer}. 090 */ 091 protected void useCachingConfigurer(CachingConfigurer config) { 092 this.cacheManager = config::cacheManager; 093 this.cacheResolver = config::cacheResolver; 094 this.keyGenerator = config::keyGenerator; 095 this.errorHandler = config::errorHandler; 096 } 097 098}