Question

Je suis en train d'intercepter un appel de méthode (AfterInsert () d'une classe de domaine) dans une application Grails. En fermeture doWithDynamicMethods de mon plugin je:

for (dc in application.domainClasses) {
    // What I'm basically doing is renaming method A to B
    // and creating a new method A with its own business logic
    // and a call to B() at the end

    def domainClass = dc.getClazz()
    def oldAfterInsert = domainClass.metaClass.afterInsert
    domainClass.metaClass."afterInsert_old" = oldAfterInsert

    dc.metaClass.afterInsert = {
        // New afterInsert() logic here

        // Call the old after insert
        delegate.afterInsert_old()
    }

}

Mais je reçois cette erreur:

No signature of method: static com.example.afterInsert_old() is applicable for argument types: () values: []

J'ai aussi essayé de l'appeler avec dc.metaClass "afterInsert_old" .invoke (délégué, nouvel objet [0]) mais je reçois.

Caused by: groovy.lang.MissingMethodException: No signature of method: groovy.lang.ExpandoMetaClass$ExpandoMetaProperty.invoke() is applicable for argument types: (com.example.DomainName, [Ljava.lang.Object;) values: [com.example.DomainName : 115, []]

Qu'est-ce que je fais mal? Comment puis-je appeler une méthode qui ne prend aucun argument?

Je sais AOP et ont également vu le plugin journal d'audit Grails à titre d'exemple. Cependant, ce qu'il fait est, pour autant que je sache, ajouter de nouvelles méthodes créées par l'utilisateur qui se déclenchent au bon moment. Je veux injecter mon code automatiquement afin que l'utilisateur n'a pas à se soucier de quoi que ce soit et je ne veux pas détruire son AfterInsert d'origine () (ou toute autre méthode est) mise en œuvre.

En outre, je voudrais faire la même chose pour les méthodes de service exposées afin d'injecter la sécurité en eux. Cependant, d'après ce que je l'ai lu ne fonctionnerait pas à cause de la BeanWrapper et parce que les services sont toujours rechargées. Quelqu'un peut-il expliquer cela mieux pour moi?

Merci d'avance.

Était-ce utile?

La solution

Je ne pense pas que vous devez renommer l'ancienne méthode. Vous pouvez le faire comme dans cet exemple :

for (dc in application.domainClasses) {
    // What I'm basically doing is renaming method A to B
    // and creating a new method A with its own business logic
    // and a call to B() at the end
    def domainClass = dc.getClazz()
    def savedAfterInsert = domainClass.metaClass.getMetaMethod('afterInsert', [] as Class[])
    domainClass.metaClass.afterInsert = {
        // New afterInsert() logic here

        // Call the old after insert
        savedAfterInsert.invoke(delegate)
    }

}

Assurez-vous que le getMetaMethod retourne la bonne méthode.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top