用于拦截Java对象之间交互的Groovy元类

用于拦截Java对象之间交互的Groovy元类,java,grails,groovy,metaprogramming,Java,Grails,Groovy,Metaprogramming,主要问题:如果我修改一个Java类的元类,那么只有当我的Groovy代码调用该Java类时,才会考虑这样的更改。但是,如果另一个Java类正在调用我修改的Java类,那么元类更改将被忽略 我猜这种行为似乎是正确的(编译的Java代码不会检查Groovy元类注册表),但我希望有人能给我一些关于如何实现我的目标的其他想法。下面是一些示例代码: A.java: public class A { A() { System.out.println("A constructor");

主要问题:如果我修改一个Java类的元类,那么只有当我的Groovy代码调用该Java类时,才会考虑这样的更改。但是,如果另一个Java类正在调用我修改的Java类,那么元类更改将被忽略


我猜这种行为似乎是正确的(编译的Java代码不会检查Groovy元类注册表),但我希望有人能给我一些关于如何实现我的目标的其他想法。下面是一些示例代码:

A.java

public class A {
   A() {
      System.out.println("A constructor");
      B b = new B();
      b.foo();
   }
}
public class B {
   B() { System.out.println("B constructor"); }
   public void foo() { System.out.println("B.foo() invoked"); }
}
javac *.java
jar cvfe java.jar Main *.class
println 'Groovy now invoking Java...'
new A()

println 'Modifying B.metaClass'
B.metaClass.foo = { -> println 'modified foo() method!' }

println 'Groovy now invoking Java...'
new A()   // <<===== I would like to see the "modified foo()" here but I don't :(

println 'Groovy creating B directly'
new B().foo()   // "modified foo()" appears here
> groovy -cp .:java.jar foo.groovy
B.java

public class A {
   A() {
      System.out.println("A constructor");
      B b = new B();
      b.foo();
   }
}
public class B {
   B() { System.out.println("B constructor"); }
   public void foo() { System.out.println("B.foo() invoked"); }
}
javac *.java
jar cvfe java.jar Main *.class
println 'Groovy now invoking Java...'
new A()

println 'Modifying B.metaClass'
B.metaClass.foo = { -> println 'modified foo() method!' }

println 'Groovy now invoking Java...'
new A()   // <<===== I would like to see the "modified foo()" here but I don't :(

println 'Groovy creating B directly'
new B().foo()   // "modified foo()" appears here
> groovy -cp .:java.jar foo.groovy
汇编

public class A {
   A() {
      System.out.println("A constructor");
      B b = new B();
      b.foo();
   }
}
public class B {
   B() { System.out.println("B constructor"); }
   public void foo() { System.out.println("B.foo() invoked"); }
}
javac *.java
jar cvfe java.jar Main *.class
println 'Groovy now invoking Java...'
new A()

println 'Modifying B.metaClass'
B.metaClass.foo = { -> println 'modified foo() method!' }

println 'Groovy now invoking Java...'
new A()   // <<===== I would like to see the "modified foo()" here but I don't :(

println 'Groovy creating B directly'
new B().foo()   // "modified foo()" appears here
> groovy -cp .:java.jar foo.groovy
foo.groovy

public class A {
   A() {
      System.out.println("A constructor");
      B b = new B();
      b.foo();
   }
}
public class B {
   B() { System.out.println("B constructor"); }
   public void foo() { System.out.println("B.foo() invoked"); }
}
javac *.java
jar cvfe java.jar Main *.class
println 'Groovy now invoking Java...'
new A()

println 'Modifying B.metaClass'
B.metaClass.foo = { -> println 'modified foo() method!' }

println 'Groovy now invoking Java...'
new A()   // <<===== I would like to see the "modified foo()" here but I don't :(

println 'Groovy creating B directly'
new B().foo()   // "modified foo()" appears here
> groovy -cp .:java.jar foo.groovy
我有一个Grails应用程序,它使用一些现有的Java JAR(字节码,无法访问其源代码)。我想拦截对这些Java类中某些方法的一些调用,但这些方法是由同一JAR中的其他Java类调用的

SpringAOP是不可能的,因为所讨论的对象不是由Spring管理的

更大的图景:我实际上是在试图解决我在以下章节中提到的问题:

我的想法是编写如下代码:

import org.codehaus.groovy.grails.orm.hibernate.validation.UniqueConstraint

class HibernateEnhancerGrailsPlugin {
    def loadBefore = ['hibernate']

    def doWithSpring = {
        UniqueConstraint.metaClass.processValidate = { final Object target, final Object propertyValue, Errors errors ->
          // no-op...
        }
    }
}

想法?

如果您无法控制这些对象的实例化,那么您可能正在查看AspectJ。Java没有groovy元类的概念,因此正如您所看到的,您所尝试的无法工作