增加util.ResourceInjectLoader功能
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.util;
|
package org.redkale.util;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -36,18 +37,27 @@ public final class ResourceFactory {
|
|||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ResourceFactory.class.getSimpleName());
|
private static final Logger logger = Logger.getLogger(ResourceFactory.class.getSimpleName());
|
||||||
|
|
||||||
|
private static final ConcurrentHashMap<Type, ResourceInjectLoader> injectLoaderMap = new ConcurrentHashMap();
|
||||||
|
|
||||||
private final ResourceFactory parent;
|
private final ResourceFactory parent;
|
||||||
|
|
||||||
private static final ResourceFactory instance = new ResourceFactory(null);
|
private static final ResourceFactory instance = new ResourceFactory(null);
|
||||||
|
|
||||||
private final List<WeakReference<ResourceFactory>> chidren = new CopyOnWriteArrayList<>();
|
private final List<WeakReference<ResourceFactory>> chidren = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
private final ConcurrentHashMap<Type, ResourceLoader> loadermap = new ConcurrentHashMap();
|
private final ConcurrentHashMap<Type, ResourceLoader> resLoaderMap = new ConcurrentHashMap();
|
||||||
|
|
||||||
private final ConcurrentHashMap<Type, ConcurrentHashMap<String, ResourceEntry>> store = new ConcurrentHashMap();
|
private final ConcurrentHashMap<Type, ConcurrentHashMap<String, ResourceEntry>> store = new ConcurrentHashMap();
|
||||||
|
|
||||||
private ResourceFactory(ResourceFactory parent) {
|
private ResourceFactory(ResourceFactory parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
if (parent == null) {
|
||||||
|
ServiceLoader<ResourceInjectLoader> loaders = ServiceLoader.load(ResourceInjectLoader.class);
|
||||||
|
Iterator<ResourceInjectLoader> it = loaders.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
this.register(it.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -565,6 +575,7 @@ public final class ResourceFactory {
|
|||||||
try {
|
try {
|
||||||
list.add(src);
|
list.add(src);
|
||||||
Class clazz = src.getClass();
|
Class clazz = src.getClass();
|
||||||
|
final boolean diyloaderflag = !injectLoaderMap.isEmpty();
|
||||||
do {
|
do {
|
||||||
if (java.lang.Enum.class.isAssignableFrom(clazz)) break;
|
if (java.lang.Enum.class.isAssignableFrom(clazz)) break;
|
||||||
final String cname = clazz.getName();
|
final String cname = clazz.getName();
|
||||||
@@ -586,6 +597,13 @@ public final class ResourceFactory {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (flag && diyloaderflag) {
|
||||||
|
injectLoaderMap.values().stream().forEach(iloader -> {
|
||||||
|
Annotation ann = field.getAnnotation(iloader.annotationType());
|
||||||
|
if (ann == null) return;
|
||||||
|
iloader.load(this, src, ann, field, attachment);
|
||||||
|
});
|
||||||
|
}
|
||||||
if (ns == null) continue;
|
if (ns == null) continue;
|
||||||
final String nsname = ns.getClass().getName();
|
final String nsname = ns.getClass().getName();
|
||||||
if (ns.getClass().isPrimitive() || ns.getClass().isArray()
|
if (ns.getClass().isPrimitive() || ns.getClass().isArray()
|
||||||
@@ -685,16 +703,21 @@ public final class ResourceFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T extends Annotation> void register(final ResourceInjectLoader<T> loader) {
|
||||||
|
if (loader == null) return;
|
||||||
|
injectLoaderMap.put(loader.annotationType(), loader);
|
||||||
|
}
|
||||||
|
|
||||||
public void register(final ResourceLoader rs, final Type... clazzs) {
|
public void register(final ResourceLoader rs, final Type... clazzs) {
|
||||||
if (clazzs == null || rs == null) return;
|
if (clazzs == null || rs == null) return;
|
||||||
for (Type clazz : clazzs) {
|
for (Type clazz : clazzs) {
|
||||||
loadermap.put(clazz, rs);
|
resLoaderMap.put(clazz, rs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourceLoader findMatchLoader(Type ft, Field field) {
|
private ResourceLoader findMatchLoader(Type ft, Field field) {
|
||||||
ResourceLoader it = this.loadermap.get(ft);
|
ResourceLoader it = this.resLoaderMap.get(ft);
|
||||||
if (it == null && field != null) it = this.loadermap.get(field.getType());
|
if (it == null && field != null) it = this.resLoaderMap.get(field.getType());
|
||||||
if (it != null) return it;
|
if (it != null) return it;
|
||||||
return parent == null ? null : parent.findMatchLoader(ft, field);
|
return parent == null ? null : parent.findMatchLoader(ft, field);
|
||||||
}
|
}
|
||||||
@@ -702,7 +725,7 @@ public final class ResourceFactory {
|
|||||||
private ResourceLoader findRegxLoader(Type ft, Field field) {
|
private ResourceLoader findRegxLoader(Type ft, Field field) {
|
||||||
if (field == null) return null;
|
if (field == null) return null;
|
||||||
Class c = field.getType();
|
Class c = field.getType();
|
||||||
for (Map.Entry<Type, ResourceLoader> en : this.loadermap.entrySet()) {
|
for (Map.Entry<Type, ResourceLoader> en : this.resLoaderMap.entrySet()) {
|
||||||
Type t = en.getKey();
|
Type t = en.getKey();
|
||||||
if (t == ft) return en.getValue();
|
if (t == ft) return en.getValue();
|
||||||
if (t instanceof Class && (((Class) t)).isAssignableFrom(c)) return en.getValue();
|
if (t instanceof Class && (((Class) t)).isAssignableFrom(c)) return en.getValue();
|
||||||
|
|||||||
25
src/org/redkale/util/ResourceInjectLoader.java
Normal file
25
src/org/redkale/util/ResourceInjectLoader.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.redkale.util;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义注入加载器
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 详情见: https://redkale.org
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
* @param <T> Annotation
|
||||||
|
*/
|
||||||
|
public interface ResourceInjectLoader<T extends Annotation> {
|
||||||
|
|
||||||
|
public void load(ResourceFactory factory, Object src, T annotation, Field field, Object attachment);
|
||||||
|
|
||||||
|
public Class<T> annotationType();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user