diff --git a/src/org/redkale/util/ResourceFactory.java b/src/org/redkale/util/ResourceFactory.java index 8884a053a..2becc2327 100644 --- a/src/org/redkale/util/ResourceFactory.java +++ b/src/org/redkale/util/ResourceFactory.java @@ -5,6 +5,7 @@ */ package org.redkale.util; +import java.lang.annotation.Annotation; import java.lang.ref.WeakReference; import java.lang.reflect.*; import java.util.*; @@ -36,18 +37,27 @@ public final class ResourceFactory { private static final Logger logger = Logger.getLogger(ResourceFactory.class.getSimpleName()); + private static final ConcurrentHashMap injectLoaderMap = new ConcurrentHashMap(); + private final ResourceFactory parent; private static final ResourceFactory instance = new ResourceFactory(null); private final List> chidren = new CopyOnWriteArrayList<>(); - private final ConcurrentHashMap loadermap = new ConcurrentHashMap(); + private final ConcurrentHashMap resLoaderMap = new ConcurrentHashMap(); private final ConcurrentHashMap> store = new ConcurrentHashMap(); private ResourceFactory(ResourceFactory parent) { this.parent = parent; + if (parent == null) { + ServiceLoader loaders = ServiceLoader.load(ResourceInjectLoader.class); + Iterator it = loaders.iterator(); + while (it.hasNext()) { + this.register(it.next()); + } + } } /** @@ -565,6 +575,7 @@ public final class ResourceFactory { try { list.add(src); Class clazz = src.getClass(); + final boolean diyloaderflag = !injectLoaderMap.isEmpty(); do { if (java.lang.Enum.class.isAssignableFrom(clazz)) break; final String cname = clazz.getName(); @@ -586,6 +597,13 @@ public final class ResourceFactory { 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; final String nsname = ns.getClass().getName(); if (ns.getClass().isPrimitive() || ns.getClass().isArray() @@ -685,16 +703,21 @@ public final class ResourceFactory { } } + public void register(final ResourceInjectLoader loader) { + if (loader == null) return; + injectLoaderMap.put(loader.annotationType(), loader); + } + public void register(final ResourceLoader rs, final Type... clazzs) { if (clazzs == null || rs == null) return; for (Type clazz : clazzs) { - loadermap.put(clazz, rs); + resLoaderMap.put(clazz, rs); } } private ResourceLoader findMatchLoader(Type ft, Field field) { - ResourceLoader it = this.loadermap.get(ft); - if (it == null && field != null) it = this.loadermap.get(field.getType()); + ResourceLoader it = this.resLoaderMap.get(ft); + if (it == null && field != null) it = this.resLoaderMap.get(field.getType()); if (it != null) return it; return parent == null ? null : parent.findMatchLoader(ft, field); } @@ -702,7 +725,7 @@ public final class ResourceFactory { private ResourceLoader findRegxLoader(Type ft, Field field) { if (field == null) return null; Class c = field.getType(); - for (Map.Entry en : this.loadermap.entrySet()) { + for (Map.Entry en : this.resLoaderMap.entrySet()) { Type t = en.getKey(); if (t == ft) return en.getValue(); if (t instanceof Class && (((Class) t)).isAssignableFrom(c)) return en.getValue(); diff --git a/src/org/redkale/util/ResourceInjectLoader.java b/src/org/redkale/util/ResourceInjectLoader.java new file mode 100644 index 000000000..26cd4ab54 --- /dev/null +++ b/src/org/redkale/util/ResourceInjectLoader.java @@ -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; + +/** + * 自定义注入加载器 + * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + * @param Annotation + */ +public interface ResourceInjectLoader { + + public void load(ResourceFactory factory, Object src, T annotation, Field field, Object attachment); + + public Class annotationType(); +}