在Groovy中自动解包包装的对象

时间:2014-03-25 16:14:26

标签: groovy scripting delegates

我有一个对象,我通过绑定传递给Groovy脚本。这个对象有数百个实现(想想“POJO”),它们都实现了一个通用的接口。

我首先创建了包装器,以便能够说pojo.property,因为我有2-3种方法可以在Java中查找这些属性,这在Groovy脚本中很麻烦。所以我创建了一个包装器,它包装原始对象并实现getProperty()和MOP的其余部分来模拟具有所有可能来源的所有属性的对象。

这很有效。但是现在,我需要用这个包装器调用方法。当然,这些方法是用Java实现的,并不知道Groovy存在或者可能存在包装器。这些方法有数以千计。简单的解决方案是向包装器添加一个方法:

public static IPojo unwrap(IPojo pojo) {
    if( pojo instanceof GroovyPojoWrapper) return ((GroovyPojoWrapper)pojo).getDelegate();

    return pojo;
}

这将允许我:

def dao = appContext[ FooDao ];
dao.save( unwrap( pojo ) );

虽然这样可行,但我现在需要在成千上万的地方打电话给我,如果我错过了,请帮助我(在这里插入你选择的虔诚)。

让我想知道是否有更好的解决方案。即:

public class Foo extends IPojo {}

public class FooDao {
    public void save( Foo foo ) {
        ...
    }
}

我希望能够在我的脚本中执行此操作:

def dao = appContext[ FooDao ];
dao.save( pojo ); // <-- How to unwrap here?

当我调用方法时,有没有办法让Groovy自动解包对象?

1 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解你的问题,但如果你想要的是能够告诉Groovy不仅可以在Pojo上调用save,而且还可以在Pojo包装器对象上调用public class Dao { public void save( Foo foo ) { System.out.println( foo ); } } ,那么你可以这样做:

Java类:

class FooWrapper {
  Foo foo
}

// tell Groovy how to unwrap anything that comes in wrapped when being saved
Dao.metaClass.save { FooWrapper wrapper -> save( wrapper.foo ) }

def foo = new Foo()
def wrappedFoo = new FooWrapper( foo: foo )

def dao = new Dao()

dao.save( foo )
dao.save( wrappedFoo )

Groovy脚本:

{{1}}

现在两个保存通话都有效。当然,Java不了解metaClass,所以只有在使用Groovy代码保存调用时才能使用它。