001/* 002 * Copyright 2002-2017 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.concurrent; 018 019import java.util.concurrent.ConcurrentMap; 020 021import org.springframework.beans.factory.BeanNameAware; 022import org.springframework.beans.factory.FactoryBean; 023import org.springframework.beans.factory.InitializingBean; 024import org.springframework.lang.Nullable; 025import org.springframework.util.StringUtils; 026 027/** 028 * {@link FactoryBean} for easy configuration of a {@link ConcurrentMapCache} 029 * when used within a Spring container. Can be configured through bean properties; 030 * uses the assigned Spring bean name as the default cache name. 031 * 032 * <p>Useful for testing or simple caching scenarios, typically in combination 033 * with {@link org.springframework.cache.support.SimpleCacheManager} or 034 * dynamically through {@link ConcurrentMapCacheManager}. 035 * 036 * @author Costin Leau 037 * @author Juergen Hoeller 038 * @since 3.1 039 */ 040public class ConcurrentMapCacheFactoryBean 041 implements FactoryBean<ConcurrentMapCache>, BeanNameAware, InitializingBean { 042 043 private String name = ""; 044 045 @Nullable 046 private ConcurrentMap<Object, Object> store; 047 048 private boolean allowNullValues = true; 049 050 @Nullable 051 private ConcurrentMapCache cache; 052 053 054 /** 055 * Specify the name of the cache. 056 * <p>Default is "" (empty String). 057 */ 058 public void setName(String name) { 059 this.name = name; 060 } 061 062 /** 063 * Specify the ConcurrentMap to use as an internal store 064 * (possibly pre-populated). 065 * <p>Default is a standard {@link java.util.concurrent.ConcurrentHashMap}. 066 */ 067 public void setStore(ConcurrentMap<Object, Object> store) { 068 this.store = store; 069 } 070 071 /** 072 * Set whether to allow {@code null} values 073 * (adapting them to an internal null holder value). 074 * <p>Default is "true". 075 */ 076 public void setAllowNullValues(boolean allowNullValues) { 077 this.allowNullValues = allowNullValues; 078 } 079 080 @Override 081 public void setBeanName(String beanName) { 082 if (!StringUtils.hasLength(this.name)) { 083 setName(beanName); 084 } 085 } 086 087 @Override 088 public void afterPropertiesSet() { 089 this.cache = (this.store != null ? new ConcurrentMapCache(this.name, this.store, this.allowNullValues) : 090 new ConcurrentMapCache(this.name, this.allowNullValues)); 091 } 092 093 094 @Override 095 @Nullable 096 public ConcurrentMapCache getObject() { 097 return this.cache; 098 } 099 100 @Override 101 public Class<?> getObjectType() { 102 return ConcurrentMapCache.class; 103 } 104 105 @Override 106 public boolean isSingleton() { 107 return true; 108 } 109 110}