Cache
using cache in your project
“There are only two hard things in Computer Science: cache invalidation and naming things”.
Tim Bray quoting Phil Karlton
在用Cache之前 , 最好先搞清楚整個Domain logic是否穩定 , and清楚自己在作什麼
Simplest Cache
Use Map<K,V>
Origional
public class UserManager {
private UserRepo repo;
public User getUser(String userId){
return repo.getUser(userId);
}
}
Add Cache
public class UserManager {
private UserRepo repo;
private Map<String,User> userCache;
...
public User getUser(String userId){
User temp = userCache.get(userId);
if(temp != null){
return temp;
} else{
return repo.getUser(userId);
}
}
}
Why use framework?
- eviction policies
- max size limit
- persistent store
- weak references keys
- statistics
Why use framework
http://java.dzone.com/articles/caching-best-practices
Cache Frameworks
- JCache
- Ehcache
- Spring Cache
- Guava
- ....
Example
Guava
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
...
try {
return graphs.get(key);
} catch (ExecutionException e) {
throw new OtherException(e.getCause());
}
Guava
@Repository
public class UserManager {
@Autowired
private UserCacheLoader cacheLoader;
private LoadingCache<String, User> users;
@PostConstruct
void init() {
users = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(1, TimeUnit.HOURS)
.build(cacheLoader);
}
public User getUser(String userId) throws ExecutionException {
return users.get(userId);
}
public void remove(String userId) {
users.invalidate(userId);
}
public void removeAll() {
users.invalidateAll();
}
}
Guava
@Component
public class UserCacheLoader extends CacheLoader<String, User> {
@Autowired
private AuthUserManager userManager;
@Override
public User load(String key) throws Exception {
return userManager.getUser(key);
}
}
Spring Cache
@Repository
public class UserManager {
private UserRepo repo;
@Cacheable("users")
public User getUser(String userId){
return repo.getUser(userId);
}
}
Spring Cache
@EnableCaching
@configuration
public class Application {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("users");
}
}
EhCache
@Repository
public class UserManager {
private UserRepo repo;
@Cacheable("users")
public User getUser(String userId){
return repo.getUser(userId);
}
@CacheEvict(value = "users", allEntries = true)
public void updateTotpCode(String code, int userSid) {
repo.update(code, userSid);
}
}
EhCache
@Configuration
@EnableCaching
public class SecurityCacheConfig {
@Autowired
private net.sf.ehcache.CacheManager cacheManager;
private int userTimeToIdleSeconds = 600;
private int userTimeToLiveSeconds = 600;
//Spring-ehcache
@PostConstruct
public void setUpCacheManager() {
CacheConfiguration userConfig =
util.buildConf("users")
.timeToIdleSeconds(userTimeToIdleSeconds)
.timeToLiveSeconds(userTimeToLiveSeconds);
Cache authUserCache = new Cache(userConfig);
cacheManager.addCache(authUserCache);
}
}
If your project has dependency on security , you need to use carefully.
Because crowd library has use ehcache
At last
-
Use carefully
-
Know what you are doing
Cache
By Mars Yang
Cache
- 640