
com.alicp.jetcache.anno.aop.CachePointcut Maven / Gradle / Ivy
The newest version!
/**
* Created on 13-09-19 20:56
*/
package com.alicp.jetcache.anno.aop;
import com.alicp.jetcache.anno.method.CacheConfigUtil;
import com.alicp.jetcache.anno.method.CacheInvokeConfig;
import com.alicp.jetcache.anno.method.ClassUtil;
import com.alicp.jetcache.anno.support.ConfigMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.asm.Type;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* @author huangli
*/
public class CachePointcut extends StaticMethodMatcherPointcut implements ClassFilter {
private static final Logger logger = LoggerFactory.getLogger(CachePointcut.class);
private ConfigMap cacheConfigMap;
private String[] basePackages;
public CachePointcut(String[] basePackages) {
setClassFilter(this);
this.basePackages = basePackages;
}
@Override
public boolean matches(Class clazz) {
boolean b = matchesImpl(clazz);
logger.trace("check class match {}: {}", b, clazz);
return b;
}
private boolean matchesImpl(Class clazz) {
if (matchesThis(clazz)) {
return true;
}
Class[] cs = clazz.getInterfaces();
if (cs != null) {
for (Class c : cs) {
if (matchesImpl(c)) {
return true;
}
}
}
if (!clazz.isInterface()) {
Class sp = clazz.getSuperclass();
if (sp != null && matchesImpl(sp)) {
return true;
}
}
return false;
}
public boolean matchesThis(Class clazz) {
String name = clazz.getName();
if (exclude(name)) {
return false;
}
return include(name);
}
private boolean include(String name) {
if (basePackages != null) {
for (String p : basePackages) {
if (name.startsWith(p)) {
return true;
}
}
}
return false;
}
private boolean exclude(String name) {
if (name.startsWith("java")) {
return true;
}
if (name.startsWith("org.springframework")) {
return true;
}
if (name.indexOf("$$EnhancerBySpringCGLIB$$") >= 0) {
return true;
}
if (name.indexOf("$$FastClassBySpringCGLIB$$") >= 0) {
return true;
}
return false;
}
@Override
public boolean matches(Method method, Class targetClass) {
boolean b = matchesImpl(method, targetClass);
if (b) {
if (logger.isDebugEnabled()) {
logger.debug("check method match true: method={}, declaringClass={}, targetClass={}",
method.getName(),
ClassUtil.getShortClassName(method.getDeclaringClass().getName()),
targetClass == null ? null : ClassUtil.getShortClassName(targetClass.getName()));
}
} else {
if (logger.isTraceEnabled()) {
logger.trace("check method match false: method={}, declaringClass={}, targetClass={}",
method.getName(),
ClassUtil.getShortClassName(method.getDeclaringClass().getName()),
targetClass == null ? null : ClassUtil.getShortClassName(targetClass.getName()));
}
}
return b;
}
private boolean matchesImpl(Method method, Class targetClass) {
if (!matchesThis(method.getDeclaringClass())) {
return false;
}
if (exclude(targetClass.getName())) {
return false;
}
String key = getKey(method, targetClass);
CacheInvokeConfig cac = cacheConfigMap.getByMethodInfo(key);
if (cac == CacheInvokeConfig.getNoCacheInvokeConfigInstance()) {
return false;
} else if (cac != null) {
return true;
} else {
cac = new CacheInvokeConfig();
CacheConfigUtil.parse(cac, method);
String name = method.getName();
Class>[] paramTypes = method.getParameterTypes();
parseByTargetClass(cac, targetClass, name, paramTypes);
if (!cac.isEnableCacheContext() && cac.getCachedAnnoConfig() == null &&
cac.getInvalidateAnnoConfigs() == null && cac.getUpdateAnnoConfig() == null) {
cacheConfigMap.putByMethodInfo(key, CacheInvokeConfig.getNoCacheInvokeConfigInstance());
return false;
} else {
cacheConfigMap.putByMethodInfo(key, cac);
return true;
}
}
}
public static String getKey(Method method, Class targetClass) {
StringBuilder sb = new StringBuilder();
sb.append(method.getDeclaringClass().getName());
sb.append('.');
sb.append(method.getName());
sb.append(Type.getMethodDescriptor(method));
if (targetClass != null) {
sb.append('_');
sb.append(targetClass.getName());
}
return sb.toString();
}
private void parseByTargetClass(CacheInvokeConfig cac, Class> clazz, String name, Class>[] paramTypes) {
if (!clazz.isInterface() && clazz.getSuperclass() != null) {
parseByTargetClass(cac, clazz.getSuperclass(), name, paramTypes);
}
Class>[] intfs = clazz.getInterfaces();
for (Class> it : intfs) {
parseByTargetClass(cac, it, name, paramTypes);
}
boolean matchThis = matchesThis(clazz);
if (matchThis) {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (methodMatch(name, method, paramTypes)) {
CacheConfigUtil.parse(cac, method);
break;
}
}
}
}
private boolean methodMatch(String name, Method method, Class>[] paramTypes) {
if (!Modifier.isPublic(method.getModifiers())) {
return false;
}
if (!name.equals(method.getName())) {
return false;
}
Class>[] ps = method.getParameterTypes();
if (ps.length != paramTypes.length) {
return false;
}
for (int i = 0; i < ps.length; i++) {
if (!ps[i].equals(paramTypes[i])) {
return false;
}
}
return true;
}
public void setCacheConfigMap(ConfigMap cacheConfigMap) {
this.cacheConfigMap = cacheConfigMap;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy