2015-02-27 3 views
2

Я использую Grails с сторонними java-библиотеками, и я бы хотел переопределить поведение в одной из этих библиотек.ExpandoMetaClass в Grails для переопределения поведения в библиотеке Java?

Я попытался сделать это в Bootstrap.groovy, например, так:

// class overrides 
    ExpandoMetaClass.enableGlobally() 
    SimpleStringFilter.metaClass.passesFilter = {Object itemId, Item item -> 
     final Property<?> p = item.getItemProperty(propertyId); 
     if (p == null) { 
      return false; 
     } 
     Object propertyValue = p.getValue(); 
     if (propertyValue == null) { 
      return false; 
     } 
     final String value = ignoreCase ? propertyValue.toString() 
       .toLowerCase() : propertyValue.toString(); 
     if (onlyMatchPrefix) { 
      if (!value.startsWith(filterString)) { 
       return false; 
      } 
     } else { 
      if (!value.contains(filterString)) { 
       return false; 
      } 
     } 
     return true; 
    } 

Я знаю, за то, что метод passesFilter в классе SimpleStringFilter получает называется, но я поставил точку останова мой код выше, и он никогда не попадал.

Для справки, подпись метода Java является:

public boolean passesFilter(Object itemId, Item item) 

Таким образом, можно один на самом деле изменить поведение в Java библиотеки с ExpandoMetaClass во всем мире? Может ли кто-нибудь объяснить поведение и нюансы его использования таким образом?

Спасибо!

+0

fyi - вы можете удалить 'ExpandoMetaClass.enableGlobally()', поскольку Grails называет это в начале процесса запуска. –

ответ

4

Проблема, с которой вы сталкиваетесь, заключается в том, что классы Java не вызывают metaClass. Groovy не может переопределять вызовы методов на классы Java, используя metaClass.

Это распространенное заблуждение, когда вы видите что-то вроде этого:

def object = new MyJavaObject() 
object.metaClass.someMethod = { ... } 

Что на самом деле происходит выше это вы создаете Groovy объект, который облегает MyJavaObject который затем позволяет этот экземпляр для вызова через метакласса.

+0

Отчасти верно - он может работать, но только для вызовов Groovy для методов Java, поскольку все вызовы метода Groovy проходят через СС. Но если класс Java вызывает этот метод, в миксе нет Groovy, и он вызовет реальный метод. Для этого вам понадобится АОП. –

+0

@BurtBeckwith Согласен, я пытался это указать. –

 Смежные вопросы

  • Нет связанных вопросов^_^