请移步: http://hacpai.com/article/1376986299174
在对项目进行优化的时候,我们可以主要从以下三个方面入手:
1 缓存
2 集群
3 异步
今天,就先说说缓存。先说说spring的缓存,下一节我们再聊聊redis
说到spring的缓存,得提到三个注解。
@Cacheable(value="accountCache") public Account getAccountByName(String accountName) { System.out.println("我进来了"); // 方法内部实现不考虑缓存逻辑,直接实现业务 logger.info("real querying account... {}", accountName); Account accountOptional = getFromDB(accountName); return accountOptional; }
<cache:annotation-driven/> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"> <property name="name" value="accountCache"/> </bean> </set> </property> </bean>
@CacheEvict(value="accountCache",key="#account.getName()") public Account updateAccount(Account account) { return updateDB(account); }上面的意思是说,如果一旦调用了updateAccount这个方法,spring就会通过参数的getName方法获得一个值,并且用这个值删除accountCache中的某一个key。
@CacheEvict(value="accountCache",allEntries=true) public void reload() { }参数allEntyies=true是什么意思,还用我说么?
@CachePut(value="accountCache",key="#account.getName()") public Account updateAccount(Account account) { return updateDB(account); }上面的 @CachePut的意思就是说,一旦我调用updateAccount方法,spring就会通过getName()取得account参数的一个值,并且以这个值为key,以updateAccount的返回值为value,更新accountCache。
@Cacheable(value="accountCache",condition="#accountName.length() <= 4") public Account getAccountByNameWithCondition(String accountName) { // 方法内部实现不考虑缓存逻辑,直接实现业务 return getFromDB(accountName); }condaition会返回一个boolean值,如果是true,才进行缓存操作。
@Cacheable(value="accountCache",key="#accountName.concat(#password)") public Account getAccount(String accountName,String password,boolean other) { // 方法内部实现不考虑缓存逻辑,直接实现业务 return getFromDB(accountName,password); }首先说明额,那个concat是java中String类的原生方法。
import java.util.Map; import org.springframework.cache.Cache; import org.springframework.cache.support.SimpleValueWrapper; public class MyCache implements Cache { private String name; private Map<String,Account> store = new HashMap<String,Account>();; public MyCache() { } public MyCache(String name) { this.name = name; } @Override public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Object getNativeCache() { return store; } @Override public ValueWrapper get(Object key) { ValueWrapper result = null; Account thevalue = store.get(key); if(thevalue!=null) { thevalue.setPassword("from mycache:"+name); //注意这一行 result = new SimpleValueWrapper(thevalue); } return result; } @Override public void put(Object key, Object value) { Account thevalue = (Account)value; store.put((String)key, thevalue); } @Override public void evict(Object key) { } @Override public void clear() { } } 再看CacheManager import java.util.Collection; import org.springframework.cache.support.AbstractCacheManager; public class MyCacheManager extends AbstractCacheManager { private Collection<? extends MyCache> caches; /** * Specify the collection of Cache instances to use for this CacheManager. */ public void setCaches(Collection<? extends MyCache> caches) { this.caches = caches; } @Override protected Collection<? extends MyCache> loadCaches() { return this.caches; } }上面的一切都已经OK,当然spring还不知道我们干的事情
<cache:annotation-driven /> <bean id="cacheManager" class="com.cache.springannotation.step6.MyCacheManager"> <property name="caches"> <set> <bean class="com.rollenholt.spring.cache.MyCache" p:name="accountCache" /> </set> </property> </bean>当我们用下面的代码测试的时候:
@Test public void getCacheMySelf(){ Account account = accountService6.getAccountByName("someone"); System.out.println("***"); logger.info("passwd={}", account.getPassword()); account = accountService6.getAccountByName("someone"); logger.info("passwd={}", account.getPassword()); }输出如下:
INFO 2015-12-04 21:07:01,695 cache.springannotation.step6.AccountService6:26 --- real querying account... someone INFO 2015-12-04 21:07:01,697 cache.springannotation.step6.AccountService6:60 --- real querying db... someone *** INFO 2015-12-04 21:07:01,697 cache.springannotation.step6.AccountService6Test:74 --- passwd=null INFO 2015-12-04 21:07:01,698 cache.springannotation.step6.AccountService6Test:76 --- passwd=from mycache:accountCache
简单的说:
spirng默认的缓存不支持内部调用
而且要缓存的方法必须是public的
就在刚才
glt想我了
glt是谁? 我媳妇
嘿嘿
参考资料: