package org.springside.examples.showcase.cache; import static org.junit.Assert.*; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import javax.sql.DataSource; import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.transaction.TransactionConfiguration; import org.springside.examples.showcase.common.entity.User; import org.springside.examples.showcase.common.service.AccountManager; import org.springside.modules.test.spring.SpringTxTestCase; import org.springside.modules.test.utils.DbUnitUtils; import com.google.common.base.Function; import com.google.common.collect.MapMaker; /** * 使用ConcurrentHashMap的本地缓存策略. * * 基于Google Collection实现: * * 1.加大并发锁数量. * 2.每个放入的对象在固定时间后过期. * 3.当key不存在时, 需要进行较长时间的计算(如访问数据库)时, 能避免并发访问造成的重复计算. * * @author calvin */ @ContextConfiguration(locations = { "/applicationContext-test.xml" }) @TransactionConfiguration(transactionManager = "defaultTransactionManager") public class MapCacheDemo extends SpringTxTestCase { private static DataSource dataSourceHolder = null; @Autowired private AccountManager accountManager; @Before public void loadDefaultData() throws Exception { if (dataSourceHolder == null) { DbUnitUtils.loadData(dataSource, "/data/default-data.xml"); dataSourceHolder = dataSource; } } @AfterClass public static void cleanDefaultData() throws Exception { DbUnitUtils.removeData(dataSourceHolder, "/data/default-data.xml"); } @Test public void normal() { Function<String, User> computingFunction = new Function<String, User>() { public User apply(String key) { User user = accountManager.getUser(key); return user; } }; ConcurrentMap<String, User> userMap = new MapMaker().concurrencyLevel(32).expiration(7, TimeUnit.DAYS) .makeComputingMap(computingFunction); assertEquals("Admin", userMap.get("1").getName()); } }