This commit is contained in:
@@ -175,7 +175,7 @@ public final class ResourceFactory {
|
||||
if (re == null) {
|
||||
map.put(name, new ResourceEntry(rs));
|
||||
} else {
|
||||
map.put(name, new ResourceEntry(rs, re.elements, autoSync));
|
||||
map.put(name, new ResourceEntry(rs, name, re.elements, autoSync));
|
||||
}
|
||||
return re == null ? null : (A) re.value;
|
||||
}
|
||||
@@ -405,7 +405,7 @@ public final class ResourceFactory {
|
||||
this.elements = new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
public ResourceEntry(T value, final List<ResourceElement> elements, boolean sync) {
|
||||
public ResourceEntry(T value, final String name, final List<ResourceElement> elements, boolean sync) {
|
||||
this.value = value;
|
||||
this.elements = elements == null ? new CopyOnWriteArrayList<>() : elements;
|
||||
if (sync && elements != null && !elements.isEmpty()) {
|
||||
@@ -433,11 +433,26 @@ public final class ResourceFactory {
|
||||
}
|
||||
}
|
||||
if (rs == null && classtype.isPrimitive()) rs = Array.get(Array.newInstance(classtype, 1), 0);
|
||||
Object oldVal = null;
|
||||
if (element.listener != null) {
|
||||
try {
|
||||
oldVal = element.field.get(dest);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
element.field.set(dest, rs);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (element.listener != null) {
|
||||
try {
|
||||
element.listener.invoke(dest, name, rs, oldVal);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -445,16 +460,41 @@ public final class ResourceFactory {
|
||||
|
||||
private static class ResourceElement<T> {
|
||||
|
||||
private static final HashMap<Class, Method> listenerMethods = new HashMap<>(); //不使用ConcurrentHashMap是因为value不能存null
|
||||
|
||||
public final WeakReference<T> dest;
|
||||
|
||||
public final Field field;
|
||||
public final Field field; //Resource 字段
|
||||
|
||||
public final Class fieldType;
|
||||
|
||||
public final Method listener;
|
||||
|
||||
public ResourceElement(T dest, Field field) {
|
||||
this.dest = new WeakReference(dest);
|
||||
this.field = field;
|
||||
this.fieldType = field.getType();
|
||||
Class t = dest.getClass();
|
||||
String tn = t.getName();
|
||||
this.listener = tn.startsWith("java.") || tn.startsWith("javax.") ? null : findListener(t);
|
||||
}
|
||||
|
||||
private static synchronized Method findListener(Class clazz) {
|
||||
Class loop = clazz;
|
||||
Method m = null;
|
||||
do {
|
||||
for (Method method : loop.getDeclaredMethods()) {
|
||||
if (method.getAnnotation(ResourceListener.class) != null
|
||||
&& method.getParameterCount() == 3
|
||||
&& String.class.isAssignableFrom(method.getParameterTypes()[0])) {
|
||||
m = method;
|
||||
m.setAccessible(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while ((loop = loop.getSuperclass()) != Object.class);
|
||||
listenerMethods.put(clazz, m);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
51
src/org/redkale/util/ResourceListener.java
Normal file
51
src/org/redkale/util/ResourceListener.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.*;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* @Resource资源被更新时的监听事件。改注解只能标记在方法参数为(String name, T newVal, T oldVal)上。
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* public class Record {
|
||||
*
|
||||
* @Resource(name = "record.id")
|
||||
* private int id;
|
||||
*
|
||||
* @Resource(name = "record.name")
|
||||
* private String name;
|
||||
*
|
||||
* @ResourceListener
|
||||
* private void changeResource(String name, Object newVal, Object oldVal) {
|
||||
* System.out.println("@Resource = " + name + " 资源变更: newVal = " + newVal + ", oldVal = " + oldVal);
|
||||
* }
|
||||
*
|
||||
* public static void main(String[] args) throws Exception {
|
||||
* ResourceFactory factory = ResourceFactory.root();
|
||||
* factory.register("record.id", "2345");
|
||||
* factory.register("record.name", "my old name");
|
||||
* Record record = new Record();
|
||||
* factory.inject(record);
|
||||
* factory.register("record.name", "my new name");
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* <p>
|
||||
* 详情见: http://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
@Documented
|
||||
@Target({METHOD})
|
||||
@Retention(RUNTIME)
|
||||
public @interface ResourceListener {
|
||||
|
||||
}
|
||||
@@ -15,35 +15,35 @@ import org.redkale.util.*;
|
||||
*/
|
||||
public class ResourceTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ResourceFactory factory = ResourceFactory.root();
|
||||
factory.register("property.id", "2345"); //注入String类型的property.id
|
||||
AService aservice = new AService();
|
||||
BService bservice = new BService("eeeee");
|
||||
public static void main(String[] args) throws Exception {
|
||||
ResourceFactory factory = ResourceFactory.root();
|
||||
factory.register("property.id", "2345"); //注入String类型的property.id
|
||||
AService aservice = new AService();
|
||||
BService bservice = new BService("eeeee");
|
||||
|
||||
factory.register(aservice); //放进Resource池内,默认的资源名name为""
|
||||
factory.register(bservice); //放进Resource池内,默认的资源名name为""
|
||||
factory.register(aservice); //放进Resource池内,默认的资源名name为""
|
||||
factory.register(bservice); //放进Resource池内,默认的资源名name为""
|
||||
|
||||
factory.inject(aservice); //给aservice注入id、bservice,bigint没有资源,所以为null
|
||||
factory.inject(bservice); //给bservice注入id、aservice
|
||||
System.out.println(aservice); //输出结果为:{id:"2345", intid: 2345, bigint:null, bservice:{name:eeeee}}
|
||||
System.out.println(bservice); //输出结果为:{name:"eeeee", id: 2345, aserivce:{id:"2345", intid: 2345, bigint:null, bservice:{name:eeeee}}}
|
||||
factory.inject(aservice); //给aservice注入id、bservice,bigint没有资源,所以为null
|
||||
factory.inject(bservice); //给bservice注入id、aservice
|
||||
System.out.println(aservice); //输出结果为:{id:"2345", intid: 2345, bigint:null, bservice:{name:eeeee}}
|
||||
System.out.println(bservice); //输出结果为:{name:"eeeee", id: 2345, aserivce:{id:"2345", intid: 2345, bigint:null, bservice:{name:eeeee}}}
|
||||
|
||||
factory.register("seqid", 200); //放进Resource池内, 同时ResourceFactory会自动更新aservice的seqid值
|
||||
System.out.println(factory.find("seqid", int.class)); //输出结果为:200
|
||||
factory.register("bigint", new BigInteger("666666666666666")); //放进Resource池内, 同时ResourceFactory会自动更新aservice对象的bigint值
|
||||
System.out.println(aservice); //输出结果为:{id:"2345", intid: 2345, bigint:666666666666666, bservice:{name:eeeee}} 可以看出seqid与bigint值都已自动更新
|
||||
factory.register("seqid", 200); //放进Resource池内, 同时ResourceFactory会自动更新aservice的seqid值
|
||||
System.out.println(factory.find("seqid", int.class)); //输出结果为:200
|
||||
factory.register("bigint", new BigInteger("666666666666666")); //放进Resource池内, 同时ResourceFactory会自动更新aservice对象的bigint值
|
||||
System.out.println(aservice); //输出结果为:{id:"2345", intid: 2345, bigint:666666666666666, bservice:{name:eeeee}} 可以看出seqid与bigint值都已自动更新
|
||||
|
||||
factory.register("property.id", "6789"); //更新Resource池内的id资源值, 同时ResourceFactory会自动更新aservice、bservice的id值
|
||||
System.out.println(aservice); //输出结果为:{id:"6789", intid: 6789, bigint:666666666666666, bservice:{name:eeeee}}
|
||||
System.out.println(bservice); //输出结果为:{name:"eeeee", id: 6789, aserivce:{id:"6789", intid: 6789, bigint:666666666666666, bservice:{name:eeeee}}}
|
||||
factory.register("property.id", "6789"); //更新Resource池内的id资源值, 同时ResourceFactory会自动更新aservice、bservice的id值
|
||||
System.out.println(aservice); //输出结果为:{id:"6789", intid: 6789, bigint:666666666666666, bservice:{name:eeeee}}
|
||||
System.out.println(bservice); //输出结果为:{name:"eeeee", id: 6789, aserivce:{id:"6789", intid: 6789, bigint:666666666666666, bservice:{name:eeeee}}}
|
||||
|
||||
bservice = new BService("ffff");
|
||||
factory.register(bservice); //更新Resource池内name=""的BService资源, 同时ResourceFactory会自动更新aservice的bservice对象
|
||||
factory.inject(bservice);
|
||||
System.out.println(aservice); //输出结果为:{id:"6789", intid: 6789, bigint:666666666666666, bservice:{name:ffff}}
|
||||
bservice = new BService("ffff");
|
||||
factory.register(bservice); //更新Resource池内name=""的BService资源, 同时ResourceFactory会自动更新aservice的bservice对象
|
||||
factory.inject(bservice);
|
||||
System.out.println(aservice); //输出结果为:{id:"6789", intid: 6789, bigint:666666666666666, bservice:{name:ffff}}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,6 +57,11 @@ class BService {
|
||||
|
||||
private String name = "";
|
||||
|
||||
@ResourceListener
|
||||
private void changeResource(String name, Object newVal, Object oldVal) {
|
||||
System.out.println("@Resource = " + name + " 资源变更: newVal = " + newVal + ", oldVal = " + oldVal);
|
||||
}
|
||||
|
||||
@java.beans.ConstructorProperties({"name"})
|
||||
public BService(String name) {
|
||||
this.name = name;
|
||||
|
||||
Reference in New Issue
Block a user