Groovy中包裹对象的自动展开

Groovy中包裹对象的自动展开,groovy,scripting,delegates,Groovy,Scripting,Delegates,我有一个通过绑定传递到Groovy脚本的对象。这个对象有数百种实现(比如“POJO”),它们都实现了一个公共接口 我首先创建了包装器,以便能够说pojo.property,因为我有2-3种方法在Java中查找这些属性,而这在Groovy脚本中很麻烦。因此,我创建了一个包装器,它包装原始对象并实现getProperty()和MOP的其余部分,以模拟具有所有可能来源的所有这些属性的对象 这很有效。但是现在,我需要用这个包装器调用方法。当然,这些方法是用Java实现的,不知道Groovy是否存在,也不

我有一个通过绑定传递到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?
defdao=appContext[FooDao];

dao.save(pojo);// 我不确定我是否完全理解您的问题,但是如果您希望能够告诉Groovy,不仅可以在Pojo上调用
save
,而且可以在Pojo包装器对象上调用,那么您可以这样做:

Java类:

public class Dao {

  public void save( Foo foo ) {
      System.out.println( foo );
  }

}
Groovy脚本:

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 )

两个保存呼叫现在都可以工作了。当然,Java不知道元类,所以只有当保存调用在Groovy代码中时,元类才起作用。

一切都包装好了吗?ie:will
dao.save(pojo.delegate)工作?还是有些东西没有包装?也许可以选择包装
dao.save
方法?DAO比POJO少吗?;-)每个POJO有一个DAO,但每个DAO有N个方法,还有其他Springbean接受POJO作为参数。名称
pojo
后面的对象始终是包装的,但我可能会执行
def list=barDao.findRelated(pojo)
,并且列表的元素将是纯pojo(未包装),除非我能找到一种方法在不更改
barDao.findRelated()的情况下包装它们
。我在想,使用AST转换可以实现类似的功能,但我以前没有这样做过,我想知道AST转换如何知道运行时类型。也许只装饰POJO的元类而不是设置委托会有所帮助?然后,当您将它发送到Java时,它仍然是一个POJO(因为它没有元类的概念),但您可以在Groovy中使用额外的方法?@tim_yates:这是一个有趣的想法。如何向元类添加属性查找?