Groovy meta-class to intercept interactions between Java objects

霸气de小男生 提交于 2019-12-24 02:23:10

问题


Main issue: It seems that if I modify a Java class's metaClass then such changes are only honored if my Groovy code is invoking that Java class. However if another Java class is invoking the Java class that I modified, then the metaClass changes are ignored.


I guess this behavior seems to be proper (the Java code that was compiled will not check the Groovy meta-class registry) but I was hoping someone can give me some other ideas on how to achieve my goals. Here's some sample code:

A.java:

public class A {
   A() {
      System.out.println("A constructor");
      B b = new B();
      b.foo();
   }
}

B.java:

public class B {
   B() { System.out.println("B constructor"); }
   public void foo() { System.out.println("B.foo() invoked"); }
}

Compilation:

javac *.java
jar cvfe java.jar Main *.class

foo.groovy:

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

Run:

> groovy -cp .:java.jar foo.groovy

I have a Grails app that uses some existing Java JARs (bytecode, no access to its source code). I'd like to intercept some calls to certain methods in these Java classes, but those methods are invoked by other Java classes in that same JAR.

Spring AOP is out of the question because the objects in question are not managed by Spring.

Bigger picture: I'm actually trying to solve the problem I stated in:

  • Why does Grails issue SELECT statements on instance save()?

My idea was to write code like the following:

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...
        }
    }
}

Thoughts?

来源:https://stackoverflow.com/questions/26003246/groovy-meta-class-to-intercept-interactions-between-java-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!