这是我最终采用的工作解决方案。精度很低:我的领域都实现了
PersistableSpring
的接口。而且,由于我正在使用反射,因此我不确定缓存过程所节省的时间不会减少多少…
applicationContext.xml
<ehcache:annotation-driven cache-manager="ehCacheManager" default-cache-key-generator="daoCacheKeyGenerator" /> <bean id="ehCacheManager" /><bean id="daoCacheKeyGenerator" />
DaoCacheKeyGenerator.java(使用
gentyref库)
public class DaoCacheKeyGenerator implements CacheKeyGenerator<DaoCacheKey> { @SuppressWarnings("unchecked") @Override public DaoCacheKey generateKey(MethodInvocation methodInvocation) { Method method = methodInvocation.getMethod(); Class<? extends GenericDao<?, ?>> daoType = (Class<? extends GenericDao<?, ?>>) methodInvocation.getThis().getClass().getInterfaces()[0]; Class<? extends Persistable<?>> domainType = getDomainType(daoType); String methodName = method.getName(); Class<?>[] parameterTypes = method.getParameterTypes(); Object[] parameters = methodInvocation.getArguments(); return new DaoCacheKey(domainType, methodName, parameterTypes, parameters); } @SuppressWarnings("unchecked") private Class<? extends Persistable<?>> getDomainType(Class<?> daoType) { Type baseDaoType = GenericTypeReflector.getExactSuperType(daoType, GenericDao.class); ParameterizedType parameterizedbaseDaoType = (ParameterizedType) baseDaoType; return (Class<? extends Persistable<?>>) parameterizedbaseDaoType.getActualTypeArguments()[0]; } @Override public DaoCacheKey generateKey(Object... data) { return null; }}DaoCacheKey.java
public class DaoCacheKey implements Serializable { private static final long serialVersionUID = 338466521373614710L; private Class<? extends Persistable<?>> domainType; private String methodName; private Class<?>[] parameterTypes; private Object[] parameters; public DaoCacheKey(Class<? extends Persistable<?>> domainType, String methodName, Class<?>[] parameterTypes, Object[] parameters) { this.domainType = domainType; this.methodName = methodName; this.parameterTypes = parameterTypes; this.parameters = parameters; } public Class<? extends Persistable<?>> getDomainType() { return domainType; } @Override public boolean equals(Object obj) { return this == obj || obj instanceof DaoCacheKey && hashCode() == obj.hashCode(); } @Override public int hashCode() { return Arrays.hashCode(new Object[] { domainType, methodName, Arrays.asList(parameterTypes), Arrays.asList(parameters) }); }}ehcache.xml
<cache name="dao" eternal="false" maxElementsInMemory="10000" overflowToDisk="false" timeToIdleSeconds="86400" timeToLiveSeconds="86400" memoryStoreEvictionPolicy="LFU"> <cacheEventListenerFactory /></cache>
DaoCacheEventListenerFactory.java
public class DaoCacheEventListenerFactory extends CacheEventListenerFactory { @Override public CacheEventListener createCacheEventListener(Properties properties) { return new DaoCacheEventListener(); }}DaoCacheEventListener.java
public class DaoCacheEventListener implements CacheEventListener { @SuppressWarnings("unchecked") @Override public void notifyElementRemoved(Ehcache cache, Element element) throws CacheException { DaoCacheKey daoCachekey = (DaoCacheKey) element.getKey(); List<Class<? extends Persistable<?>>> impacts = getoneToManyImpacts(daoCachekey.getDomainType()); for (DaoCacheKey daoCachedkey : (List<DaoCacheKey>) cache.getKeys()) { if (impacts.contains(daoCachedkey.getDomainType())) { cache.remove(daoCachedkey); } } } @SuppressWarnings("unchecked") private List<Class<? extends Persistable<?>>> getoneToManyImpacts(Class<? extends Persistable<?>> domainType) { List<Class<? extends Persistable<?>>> impacts = new ArrayList<Class<? extends Persistable<?>>>(); impacts.add(domainType); for (Method method : domainType.getDeclaredMethods()) { if (method.isAnnotationPresent(OneToMany.class)) { ParameterizedType parameterizedType = (ParameterizedType) method.getGenericReturnType(); Class<? extends Persistable<?>> impactedDomainType = (Class<? extends Persistable<?>>) parameterizedType.getActualTypeArguments()[0]; if (!impacts.contains(impactedDomainType)) { impacts.addAll(getoneToManyImpacts(impactedDomainType)); } } } return impacts; } @Override public void notifyElementPut(Ehcache cache, Element element) throws CacheException { } @Override public void notifyElementUpdated(Ehcache cache, Element element) throws CacheException { } @Override public void notifyElementExpired(Ehcache cache, Element element) { } @Override public void notifyElementEvicted(Ehcache cache, Element element) { } @Override public void notifyRemoveAll(Ehcache cache) { } @Override public void dispose() { } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); }}希望能有所帮助
;)



