com.jn.sqlhelper.datasource.key.MethodDataSourceKeyRegistry Maven / Gradle / Ivy
package com.jn.sqlhelper.datasource.key;
import com.jn.langx.annotation.NonNull;
import com.jn.langx.registry.Registry;
import com.jn.langx.util.Preconditions;
import com.jn.langx.util.collection.Collects;
import com.jn.langx.util.function.Consumer2;
import com.jn.langx.util.function.Predicate2;
import com.jn.langx.util.struct.Holder;
import com.jn.sqlhelper.datasource.key.parser.DataSourceAnnotationParser;
import com.jn.sqlhelper.datasource.key.parser.DataSourceKeyAnnotationParser;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 该类有两个作用:
* 1)自动的解析出要执行的方法是在哪个数据源上。执行过程:对于要执行的方法,解析它或者它所在的类,或者接口上上声明的用于决定使用哪种数据源的注解。
* 2)对解析过的方法,进行cache, 避免二次解析。
*/
public class MethodDataSourceKeyRegistry implements Registry {
/**
* 这里的 DataSourceKey,可以是一个确切的 key,也可以是个 keyPattern。
* 不论是确切的key,还是个keyPattern,在DataSourceRegister里进行pattern匹配的。
*/
private final ConcurrentHashMap> methodDataSourceKeyCache = new ConcurrentHashMap>();
/**
* parser 缓存
*/
private Map, DataSourceKeyAnnotationParser> annotationParserMap = new LinkedHashMap, DataSourceKeyAnnotationParser>();
public MethodDataSourceKeyRegistry() {
registerDataSourceKeyParser(new DataSourceAnnotationParser());
}
@Override
public void register(DataSourceKey dataSourceKeyHolder) {
throw new UnsupportedOperationException();
}
@Override
public void register(Method method, DataSourceKey dataSourceKey) {
Preconditions.checkNotNull(dataSourceKey);
methodDataSourceKeyCache.putIfAbsent(method, new Holder(dataSourceKey));
}
public void registerDataSourceKeyParser(DataSourceKeyAnnotationParser dataSourceKeyAnnotationParser) {
if (dataSourceKeyAnnotationParser != null && dataSourceKeyAnnotationParser.getAnnotation() != null) {
annotationParserMap.put(dataSourceKeyAnnotationParser.getAnnotation(), dataSourceKeyAnnotationParser);
}
}
@Override
@NonNull
public DataSourceKey get(final Method method) {
Holder holder = methodDataSourceKeyCache.get(method);
if (holder == null) {
// 第一次用到该方法
synchronized (this) {
final Holder holder0 = new Holder();
Collects.forEach(annotationParserMap, new Consumer2, DataSourceKeyAnnotationParser>() {
@Override
public void accept(Class extends Annotation> annotationClass, DataSourceKeyAnnotationParser parser) {
DataSourceKey key = parser.parse(method);
if (key != null) {
holder0.set(key);
}
}
}, new Predicate2, DataSourceKeyAnnotationParser>() {
@Override
public boolean test(Class extends Annotation> key, DataSourceKeyAnnotationParser value) {
return !holder0.isNull();
}
});
methodDataSourceKeyCache.putIfAbsent(method, holder0);
holder = methodDataSourceKeyCache.get(method);
}
}
return holder.get();
}
}