Динамический прокси для конкретных классов

Я хочу определить метод перехватчика в программе Java, другими словами, я хочу иметь поведение, которое выполняется при каждом вызове метода. Это приложение не выполняется на сервере приложений, поэтому я не могу использовать EJB для вызова перехватчиков. Я нашел хороший Proxy API в стандартных библиотеках Java, но его ограничил, потому что ему нужен интерфейс в создании прокси:

 Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                      new Class[] { Foo.class },
                                      handler);

Есть ли аналогичный API, который не заставляет Foo.class объявляться как интерфейс?

Ответы

Ответ 1

Почему бы не использовать CGLIB? Подробнее см. в этой статье.

Что делать, если вы хотите проксировать устаревшие классы, у которых нет интерфейсов? Вы можете использовать CGLIB. CGLIB - мощный, высокопроизводительный код. Под обложкой используется ASM, небольшая, но быстро байт-кода, чтобы преобразовать существующий байт-код в генерировать новые классы. CGLIB быстрее, чем динамический прокси JDK подход. По сути, он динамически генерирует подкласс для переопределения не конечные методы прокси-класса и подключают крючки, которые перейдите к пользовательским перехватчикам.

Ответ 2

К сожалению, такого API для классов нет. Многие системы используют библиотеки генерации байт-кода, такие как CGLIB, для достижения этого.

Ответ 3

Вы можете попробовать один из насмешливых классов. Самый простой подход может быть к подклассу, вашему классу. Или вы можете использовать AOP для ввода нужного кода ведения журнала.

Ответ 4

sun.misc.ProxyGenerator может использоваться для создания прокси-классов и не проверяет, что их "интерфейсы" - это все интерфейсы. Его метод generateClassFile дает вам байт-код в виде байтового массива, который вы можете сохранить, чтобы ссылаться на будущие сборки или изменять с помощью сторонних инструментов.

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