Инструментирование объекта анонимного внутреннего класса Java - PullRequest
1 голос
/ 10 февраля 2012

Итак, учитывая следующий код:

public MyInterface getMyInterface() {
    return new MyInterface() {
        public SomethingElse getSomethingElse() {
           // ....
        }
    }
}

...
MyInterface obj = getMyInterface();

Есть ли способ обработать вызов getSomethingElse () для этого obj? Чтобы войти и сделать какую-то модификацию байт-кода или что-то еще?

У меня есть рабочий код, который в другой ситуации (назовите это «временем разработки») я хочу добавить трассировку / протоколирование и такой код для помощи в устранении неполадок и анализе. Производительность важна для производственного случая, поэтому я хочу оставить ее без дополнительных затрат на трассировку / ведение журнала. Но в ситуации времени проектирования я хочу получить всю информацию о трассировке.

Ответы [ 3 ]

1 голос
/ 18 февраля 2012

Да, можно делать то, что вы просите, хотя определенно есть лучшие способы сделать это - наиболее очевидным было бы создание реализации MyInterface по умолчанию, а затем его подкласса «трассировки», который расширяет и журналы перед вызовом версии суперкласса.

Если инструментарий является единственным вариантом, то при запуске во время разработки вы можете запустить свой проект с помощью Java-агента в Java 5 или добавить Java-агент в путь к классам во время выполнения в Java 6. См. Документацию по инструментальным средствам . .

Для инструментов класса вы, вероятно, захотите использовать такой инструмент, как ASM . Шаги будут примерно такими:

  1. В своем классе агента реализуйте java.lang.instrument.ClassFileTransformer.
  2. В вашем методе agentmain () или premain () запрос на преобразование классов.
  3. Когда вы получаете вызов метода transform , вы можете проверить, реализует ли класс MyInterface, используя Class.getInterfaces ().
  4. При желании вы можете проверить, является ли его Class.getEnclosingClass () тем классом, в котором вы написали / нашли этот код.
  5. Если Класс проходит эти проверки работоспособности, то создайте ClassWriter, который добавляет запись в метод getSomethingElse (). ASMifier очень помогает при попытке выяснить, как сгенерировать нужный код.

Тогда в производстве ни один из этого кода не будет существовать. В процессе разработки вы добавляете свой Java-агент в свою среду, что позволит вам выполнять отладку.

Опять же, есть почти наверняка лучшие способы сделать это, но есть веские причины использовать инструментарий, и это мини-курс для этого.

Надеюсь, это поможет,

1 голос
/ 10 февраля 2012

Если вы хотите включить вход в систему при разработке, самое простое, что нужно сделать, это

if(LOGGER.isDebugEnabled())
   LOGGER.debug("my debug message");

Добавленные накладные расходы составляют менее наносекунды, поэтому, даже если вы работаете в системе, где каждая нано-секунда отсчитывает, это все же лучший шаблон для использования.


Вы можете получить класс с

 Class.forName("package.OuterClass$NNN");

Вам нужно вызвать конструктор, который принимает экземпляр внешнего класса.

0 голосов
/ 10 февраля 2012

Звучит как хороший пример использования аспектов .

Вы можете просто применить код ведения журнала / трассировки к любым методам, которые вы хотите использовать в своей среде тестирования, и пропустить их при переходе в производство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...