场景:物流系统库存管理模块 : 用户登录、仓库增删改查spring JdbcTemplate实现数据层操作。
为了减少DB的IO次数,配置AOP切面,用Map手动实现一个缓存:在添加、修改、删除仓库时,清空缓存;查询仓库列表或者查询每个仓库信息时,加载数据到缓存.
实现:
切面:
package main.com.store.aop; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import main.com.store.domain.Store; import org.aspectj.lang.ProceedingJoinPoint; /** * AOP缓存切面 * * @author lee * */ @SuppressWarnings("all") public class CacheAspect { // 为了线程安全,使用Collections.synchronizedMap(new HashMap()); private static Map<String, Object> aopCahche = Collections.synchronizedMap(new HashMap<String, Object>()); // private static Map<String, Object> aopCahche = new HashMap<String, Object>(); public static Map<String, Object> getAopCahche() { return aopCahche; } public static void setAopCahche(Map<String, Object> aopCahche) { CacheAspect.aopCahche = aopCahche; } public static List<Store> doCacheList(ProceedingJoinPoint point) throws Throwable { List<Store> result = (List<Store>) point.proceed(); return result; } public static Store doCacheSingle(ProceedingJoinPoint point) throws Throwable { Store result = (Store) point.proceed(); return result; } public static void clearCache() { aopCahche = new HashMap<String, Object>(); System.out.println("清空缓存成功!"); } }
Dao
package main.com.store.dao; import java.util.List; import main.com.store.domain.Store; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; @SuppressWarnings("all") public class StoreDao extends HibernateDaoSupport { /** * 查询所有仓库信息 * * @return */ public List<Store> findAllStores() { List<Store> stores = this.getHibernateTemplate().find("from Store"); return stores; } /** * 增加仓库信息 * * @param store */ public void add(Store store) { this.getHibernateTemplate().save(store); } /** * 删除仓库信息 * * @param id */ public void delete(Store store) { this.getHibernateTemplate().delete(store); } /** * 根据id查询仓库信息 * * @param id * @return */ public Store getStoreById(String id) { Store result = null; result = this.getHibernateTemplate().get(Store.class, id); return result; } /** * 修改仓库信息 * * @param store */ public void update(Store store) { this.getHibernateTemplate().update(store); } }
VO
package main.com.store.domain; /** * 仓库 * * @author lee * */ public class Store { /** 仓库编号 */ private String id; /** 仓库名称 */ private String name; /** 仓库所在地 */ private String addr; /** 仓库管理人员 */ private String manager; public Store() { } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } public String getManager() { return manager; } public void setManager(String manager) { this.manager = manager; } @Override public String toString() { return "Store [id=" + id + ", name=" + name + ", addr=" + addr + ", manager=" + manager + "]"; } }
Service
package main.com.store.service; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import main.com.store.aop.CacheAspect; import main.com.store.dao.StoreDao; import main.com.store.domain.Store; public class StoreService { private StoreDao storeDao; public void setStoreDao(StoreDao storeDao) { this.storeDao = storeDao; } /** * 查询所有仓库信息 */ public List<Store> findAllStores() { List<Store> stores = new ArrayList<Store>(); // 获取缓存中值,如果有 Map<String, Object> cacheMap = CacheAspect.getAopCahche(); Set<Entry<String, Object>> entrySet = cacheMap.entrySet(); if (!CacheAspect.getAopCahche().isEmpty()) { System.out.println("查询缓存"); for (Entry<String, Object> entry : entrySet) { String key = entry.getKey().toString(); System.out.println(key); Store store = (Store) entry.getValue(); stores.add(store); } } else { System.out.println("查询数据库"); stores = storeDao.findAllStores(); for (Store store : stores) { cacheMap.put(store.getId(), store); } } return stores.isEmpty() ? null : stores; } /** * 根据id查询仓库信息 * * @param id * @return */ public Store findStoreById(String id) { Store store = new Store(); // 获取缓存中值,如果有 Map<String, Object> cacheMap = CacheAspect.getAopCahche(); Set<Entry<String, Object>> entrySet = cacheMap.entrySet(); if (!cacheMap.isEmpty()) { System.out.println("查询缓存"); for (Entry<String, Object> entry : entrySet) { String key = entry.getKey().toString(); System.out.println(key); store = (Store) entry.getValue(); } } else { System.out.println("数据库"); store = storeDao.getStoreById(id); cacheMap.put(store.getId(), store); } return store; } /** * 增加仓库 * * @param store */ public void add(Store store) { storeDao.add(store); } /** * 删除仓库信息 * * @param id */ public void delete(Store store) { storeDao.delete(store); } /** * 修改仓库信息 * * @param store */ public void update(Store store) { storeDao.update(store); } }
applicationContext.xml
<bean id="cacheAdvice" class="main.com.store.aop.CacheAspect" /> <aop:config proxy-target-class="true"> <aop:aspect ref="cacheAdvice"> <aop:pointcut expression="execution(* main.com.store.service.StoreService.findAllStores(..))" id="cacheList" /> <aop:around method="doCacheList" pointcut-ref="cacheList"/> <aop:pointcut expression="execution(* main.com.store.service.StoreService.findStoreById(..))" id="cacheSingle" /> <aop:around method="doCacheSingle" pointcut-ref="cacheSingle"/> <aop:pointcut expression="execution(* main.com.store.service.StoreService.add(..))" id="clearAdd" /> <aop:pointcut expression="execution(* main.com.store.service.StoreService.delete(..))" id="clearDelete" /> <aop:pointcut expression="execution(* main.com.store.service.StoreService.update(..))" id="clearUpdate" /> <aop:before method="clearCache" pointcut-ref="clearAdd"/> <aop:before method="clearCache" pointcut-ref="clearDelete"/> <aop:before method="clearCache" pointcut-ref="clearUpdate"/> </aop:aspect> </aop:config> <!-- 仓库管理 --> <bean id="storeDao" class="main.com.store.dao.StoreDao"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="storeService" class="main.com.store.service.StoreService"> <property name="storeDao" ref="storeDao" /> </bean> <bean id="storeAction" class="main.com.store.web.StoreAction"> <property name="storeService" ref="storeService" /> </bean>
OK ! 完工!