This commit is contained in:
Redkale
2017-05-30 07:22:45 +08:00
parent 369a70e857
commit 14238a0203

View File

@@ -18,7 +18,7 @@ import javax.annotation.Resource;
* 依赖注入功能主类 <br>
*
* 如果&#64;Resource(name = "$") 表示资源name采用所属对象的name <br>
* 如果没有&#64;Resource 则会取对象的getResourceName()方法值(若存在)
* 如果没有&#64;Resource且对象实现了Resourcable, 则会取对象的resourceName()方法值
* <blockquote><pre>
* name规则:
* 1: "$"有特殊含义, 不能表示"$"资源本身
@@ -50,16 +50,31 @@ public final class ResourceFactory {
this.parent = parent;
}
/**
* 获取根ResourceFactory
*
* @return ResourceFactory
*/
public static ResourceFactory root() {
return instance;
}
/**
* 创建ResourceFactory子节点
*
* @return ResourceFactory
*/
public ResourceFactory createChild() {
ResourceFactory child = new ResourceFactory(this);
this.chidren.add(new WeakReference<>(child));
return child;
}
/**
* 获取所有ResourceFactory子节点
*
* @return List
*/
public List<ResourceFactory> getChildren() {
List<ResourceFactory> result = new ArrayList<>();
for (WeakReference<ResourceFactory> ref : chidren) {
@@ -69,105 +84,267 @@ public final class ResourceFactory {
return result;
}
/**
* 清空当前ResourceFactory注入资源
*
*/
public void release() {
this.store.clear();
}
/**
* 检查资源名是否合法
* <blockquote><pre>
* name规则:
* 1: "$"有特殊含义, 不能表示"$"资源本身
* 2: 只能是字母、数字、(短横)-、(下划线)_、点(.)的组合
* </pre></blockquote>
* <p>
* @param name
*/
public void checkName(String name) {
if (name == null || (!name.isEmpty() && !name.matches("^[a-zA-Z0-9_;\\-\\.\\[\\]\\(\\)]+$"))) {
throw new IllegalArgumentException("Resource.name(" + name + ") contains illegal character, must be (a-z,A-Z,0-9,_,.,(,),-,[,])");
}
}
/**
* 将对象指定类型且name=""注入到资源池中,并同步已被注入的资源
*
* @param <A> 泛型
* @param clazz 资源类型
* @param rs 资源对象
*
* @return 旧资源对象
*/
public <A> A register(final Class<? extends A> clazz, final A rs) {
return register(true, clazz, rs);
}
/**
* 将对象指定类型且name=""注入到资源池中
*
* @param <A> 泛型
* @param autoSync 是否同步已被注入的资源
* @param clazz 资源类型
* @param rs 资源对象
*
* @return 旧资源对象
*/
public <A> A register(final boolean autoSync, final Class<? extends A> clazz, final A rs) {
return register(autoSync, "", clazz, rs);
}
/**
* 将对象以name=""注入到资源池中,并同步已被注入的资源
*
* @param <A> 泛型
* @param rs 资源对象
*
* @return 旧资源对象
*/
public <A> A register(final A rs) {
return register(true, rs);
}
/**
* 将对象以name=""注入到资源池中,并同步已被注入的资源
*
* @param <A> 泛型
* @param autoSync 是否同步已被注入的资源
* @param rs 资源对象
*
* @return 旧资源对象
*/
public <A> A register(final boolean autoSync, final A rs) {
if (rs == null) return null;
return (A) register(autoSync, "", rs);
}
public void register(final Type clazz, final ResourceLoader rs) {
if (clazz == null || rs == null) return;
loadermap.put(clazz, rs);
}
public void register(final ResourceLoader rs, final Type... clazzs) {
if (clazzs == null || rs == null) return;
for (Type clazz : clazzs) {
loadermap.put(clazz, rs);
}
}
/**
* 将boolean对象以指定资源名注入到资源池中并同步已被注入的资源
*
* @param name 资源名
* @param value 资源值
*
*/
public void register(final String name, final boolean value) {
register(true, name, boolean.class, value);
}
/**
* 将boolean对象以指定资源名注入到资源池中
*
* @param autoSync 是否同步已被注入的资源
* @param name 资源名
* @param value 资源值
*
*/
public void register(final boolean autoSync, final String name, final boolean value) {
register(autoSync, name, boolean.class, value);
}
/**
* 将byte对象以指定资源名注入到资源池中并同步已被注入的资源
*
* @param name 资源名
* @param value 资源值
*
*/
public void register(final String name, final byte value) {
register(true, name, byte.class, value);
}
/**
* 将byte对象以指定资源名注入到资源池中
*
* @param autoSync 是否同步已被注入的资源
* @param name 资源名
* @param value 资源值
*
*/
public void register(final boolean autoSync, final String name, final byte value) {
register(autoSync, name, byte.class, value);
}
/**
* 将short对象以指定资源名注入到资源池中并同步已被注入的资源
*
* @param name 资源名
* @param value 资源值
*
*/
public void register(final String name, final short value) {
register(true, name, short.class, value);
}
/**
* 将short对象以指定资源名注入到资源池中
*
* @param autoSync 是否同步已被注入的资源
* @param name 资源名
* @param value 资源值
*
*/
public void register(final boolean autoSync, final String name, final short value) {
register(autoSync, name, short.class, value);
}
/**
* 将int对象以指定资源名注入到资源池中并同步已被注入的资源
*
* @param name 资源名
* @param value 资源值
*
*/
public void register(final String name, final int value) {
register(true, name, int.class, value);
}
/**
* 将int对象以指定资源名注入到资源池中
*
* @param autoSync 是否同步已被注入的资源
* @param name 资源名
* @param value 资源值
*
*/
public void register(final boolean autoSync, final String name, final int value) {
register(autoSync, name, int.class, value);
}
/**
* 将float对象以指定资源名注入到资源池中并同步已被注入的资源
*
* @param name 资源名
* @param value 资源值
*
*/
public void register(final String name, final float value) {
register(true, name, float.class, value);
}
/**
* 将float对象以指定资源名注入到资源池中
*
* @param autoSync 是否同步已被注入的资源
* @param name 资源名
* @param value 资源值
*
*/
public void register(final boolean autoSync, final String name, final float value) {
register(autoSync, name, float.class, value);
}
/**
* 将long对象以指定资源名注入到资源池中并同步已被注入的资源
*
* @param name 资源名
* @param value 资源值
*
*/
public void register(final String name, final long value) {
register(true, name, long.class, value);
}
/**
* 将long对象以指定资源名注入到资源池中
*
* @param autoSync 是否同步已被注入的资源
* @param name 资源名
* @param value 资源值
*
*/
public void register(final boolean autoSync, final String name, final long value) {
register(autoSync, name, long.class, value);
}
/**
* 将double对象以指定资源名注入到资源池中并同步已被注入的资源
*
* @param name 资源名
* @param value 资源值
*
*/
public void register(final String name, final double value) {
register(true, name, double.class, value);
}
/**
* 将double对象以指定资源名注入到资源池中
*
* @param autoSync 是否同步已被注入的资源
* @param name 资源名
* @param value 资源值
*
*/
public void register(final boolean autoSync, final String name, final double value) {
register(autoSync, name, double.class, value);
}
/**
* 将对象以指定资源名注入到资源池中,并同步已被注入的资源
*
* @param <A> 泛型
* @param name 资源名
* @param rs 资源对象
*
* @return 旧资源对象
*/
public <A> A register(final String name, final A rs) {
return register(true, name, rs);
}
/**
* 将对象以指定资源名注入到资源池中
*
* @param <A> 泛型
* @param autoSync 是否同步已被注入的资源
* @param name 资源名
* @param rs 资源对象
*
* @return 旧资源对象
*/
public <A> A register(final boolean autoSync, final String name, final A rs) {
checkName(name);
final Class<?> claz = rs.getClass();
@@ -182,14 +359,45 @@ public final class ResourceFactory {
}
}
/**
* 将对象以指定资源名和类型注入到资源池中,并同步已被注入的资源
*
* @param <A> 泛型
* @param name 资源名
* @param clazz 资源类型
* @param rs 资源对象
*
* @return 旧资源对象
*/
public <A> A register(final String name, final Class<? extends A> clazz, final A rs) {
return register(true, name, clazz, rs);
}
/**
* 将对象以指定资源名和类型注入到资源池中,并同步已被注入的资源
*
* @param <A> 泛型
* @param name 资源名
* @param clazz 资源类型
* @param rs 资源对象
*
* @return 旧资源对象
*/
public <A> A register(final String name, final Type clazz, final A rs) {
return register(true, name, clazz, rs);
}
/**
* 将对象以指定资源名和类型注入到资源池中
*
* @param <A> 泛型
* @param autoSync 是否同步已被注入的资源
* @param name 资源名
* @param clazz 资源类型
* @param rs 资源对象
*
* @return 旧资源对象
*/
public <A> A register(final boolean autoSync, final String name, final Type clazz, final A rs) {
checkName(name);
ConcurrentHashMap<String, ResourceEntry> map = this.store.get(clazz);
@@ -211,9 +419,19 @@ public final class ResourceFactory {
return re == null ? null : (A) re.value;
}
public <A> boolean contains(String name, Class<? extends A> clazz) {
/**
* 判断是否包含指定资源名和资源类型的资源对象
*
* @param <A> 泛型
* @param recursive 是否遍历父节点
* @param name 资源名
* @param clazz 资源类型
*
* @return 是否存在
*/
public <A> boolean contains(boolean recursive, String name, Class<? extends A> clazz) {
Map<String, ResourceEntry> map = this.store.get(clazz);
return map == null ? false : map.containsKey(name);
return map == null ? ((recursive && parent != null) ? parent.contains(recursive, name, clazz) : false) : map.containsKey(name);
}
public <A> A find(Class<? extends A> clazz) {
@@ -225,6 +443,23 @@ public final class ResourceFactory {
return re == null ? null : (A) re.value;
}
public <A> A find(String name, Class<? extends A> clazz) {
ResourceEntry<A> re = findEntry(name, clazz);
return re == null ? null : re.value;
}
public <A> A findChild(final String name, final Class<? extends A> clazz) {
A rs = find(name, clazz);
if (rs != null) return rs;
for (Map.Entry<Type, ConcurrentHashMap<String, ResourceEntry>> en : this.store.entrySet()) {
if (!(en.getKey() instanceof Class)) continue;
if (!clazz.isAssignableFrom((Class) en.getKey())) continue;
ResourceEntry v = en.getValue().get(name);
if (v != null) return (A) v.value;
}
return null;
}
private ResourceEntry findEntry(String name, Type clazz) {
Map<String, ResourceEntry> map = this.store.get(clazz);
if (map != null) {
@@ -254,11 +489,6 @@ public final class ResourceFactory {
return list;
}
public <A> A find(String name, Class<? extends A> clazz) {
ResourceEntry<A> re = findEntry(name, clazz);
return re == null ? null : re.value;
}
private <A> ResourceEntry<A> findEntry(String name, Class<? extends A> clazz) {
Map<String, ResourceEntry> map = this.store.get(clazz);
if (map != null) {
@@ -269,18 +499,6 @@ public final class ResourceFactory {
return null;
}
public <A> A findChild(final String name, final Class<? extends A> clazz) {
A rs = find(name, clazz);
if (rs != null) return rs;
for (Map.Entry<Type, ConcurrentHashMap<String, ResourceEntry>> en : this.store.entrySet()) { //不用forEach为兼容JDK 6
if (!(en.getKey() instanceof Class)) continue;
if (!clazz.isAssignableFrom((Class) en.getKey())) continue;
ResourceEntry v = en.getValue().get(name);
if (v != null) return (A) v.value;
}
return null;
}
public <T> boolean inject(final Object src) {
return inject(src, null);
}
@@ -410,6 +628,13 @@ public final class ResourceFactory {
}
}
public void register(final ResourceLoader rs, final Type... clazzs) {
if (clazzs == null || rs == null) return;
for (Type clazz : clazzs) {
loadermap.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());