致电所有制定者

时间:2016-01-24 21:10:57

标签: java

我想在调用任何类的setter时调用方法setDirty 有没有一种简单的方法可以在Java中实现这一点而不需要代码重复(在每个setter上调用setDirty)?

如果这是一个愚蠢的问题,我很乐意删除它,但我似乎无法找到快速答案。

2 个答案:

答案 0 :(得分:1)

这不是一个愚蠢的问题,但在普通的Java中没有简单的方法来实现它。使用AspectJ或Groovy AST转换,您可以自动将调用插入到每个setter中。

答案 1 :(得分:0)

我找到了一个使用Java反射的解决方案。

阅读此问题:Capture method calls in Java

使用Dynamic proxy class,您可以代理setter所在的类,然后在调用set方法时触发setDirty。

public interface A { void m(); }

public class AImpl implements A { public void m() {} }

public class EnqueueProxy implements java.lang.reflect.InvocationHandler {

    private Object obj;
    private Method method_setDirty = null;

    public static Object newInstance(Object obj) {

        if( null==method_setDirty ){
            // Gets setDirty method 
            Method[] methods = obj.getClass().getDeclaredMethods();
            int ms_length = methods.length;
            for (int i = 0; i < ms_length; i++){
                if("setDirty".equals(methods[i].getName()) ){
                    method_setDirty = methods[i];
                    break;
                }
            }
        }

        return java.lang.reflect.Proxy.newProxyInstance(
            obj.getClass().getClassLoader(),
            obj.getClass().getInterfaces(),
            new EnqueueProxy(obj));
    }

    private EnqueueProxy(Object obj) {
        this.obj = obj;
    }

    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        try {
            new MethodInvocation(obj, m, args);
            if( "set".equals(m.getName().substring(0,3)) ){
                new MethodInvocation(obj, method_setDirty, args);
            }
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        } catch (Exception e) {
            throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
        }
        return null;
    }
}

现在你可以用这个打电话给你的课:

A a = (A) EnqueueProxy.newInstance(new AImpl());
a.setSomething();