Ответ 1
Посмотрите ProxyWeavingHook из прокси-модуля Apache Aries. Он использует библиотеку ASM напрямую, чтобы изменить байт-код так на более низкий уровень.
Есть ли у кого-нибудь примеры использования OSGi 4.3+ Weaving Hook Service? Как насчет AspectJ, ASM, JavaAssist? Кто-нибудь действительно использует OSGi WeavingHooks?
Пример в разделе 56.2 OSGi Core 5.0.0 просто не учитывает фактического ткачества и говорит, что "окончательное плетение остается в качестве упражнения для читателя".
Моя цель:
Моя проблема в основном С# 3.
В настоящее время я пытаюсь использовать AspectJ WeavingAdaptor, чтобы выполнить переплетение, но у меня возникают проблемы с получением моей аспектной библиотеки в нем, поскольку он ожидает, что java.net.URL [] aspectURLs в конструкторе будет либо баночками, либо каталогами, которые он может найти в файловой системе, а не в связках. Кроме того, я не уверен, как обращаться с любыми новыми классами, сгенерированными ткачиком через обратные вызовы методу acceptClass (String name, bytes []) GeneratedClassHandler.
Возможно, WeavingAdaptor не подходит для начала моего плетения? Или, может быть, я не должен использовать AspectJ?
MyAnnotation.java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
MyWeavingHook.java
public class MyWeavingHook implements WeavingHook {
public class MyWeavingClassloader implements WeavingClassLoader {
private Bundle b;
public MyWeavingClassLoader(Bundle b) {
this.b = b;
}
void acceptClass(java.lang.String name, byte[] bytes) {
//no way to get this back into the woven classes bundle classloader?
}
URL[] getAspectURLs() {
//how do I get a handle to my aspect library that AspectJ can understand?
}
}
public void weave(WovenClass myclass) {
Bundle b = Framework.getBundle(MyWeavingHook.class);
WeavingClassLoader wc = new WeavingClassLoader(b);
WeavingAdaptor w = new WeavingAdaptor(wc);
if (shouldWeave(myclass))
myclass.setBytes(w.weave(myClass.getBytes()));
//should catch exceptions
}
private boolean shouldWeave(WovenClass myclass) {
//not sure of the best logic to pick which classes to weave yet
}
}
MyAspect.aj
privileged aspect MyAspect {
after() : set(* *) && @annotation(MyAnnotation) {
//send EventAdmin event
}
}
MyTestClass.java
public class MyTestClass {
@MyAnnotation
private int myField;
public void doSomething() {
//do stuff with myField
}
}
Я мог бы использовать Spring AOP, но я хочу, чтобы это работало для любого пакета, а не только beans, созданного с помощью Spring или Blueprint. Кроме того, Equinox Weaving, похоже, пока не использует опцию привязки OSGi, и я не хочу привязываться к Equinox. У меня нет проблем с утилитой AspectJ, если что-то еще работает лучше.
Ссылка на аналогичный вопрос: Можно ли манипулировать байт-кодом при использовании OSGi?
UPDATE:
Конечный результат: я просто использовал Equinox Aspects и установил его в Karaf. Было 3 пакета, одна библиотека и системное свойство. Я буду использовать его до тех пор, пока они не обновят его для нас OSGi, или я напишу свои собственные перетаскивания OSGi, чтобы использовать код AspectJ, похожий на Equinox Aspects. Мне не нравятся показатели ткачества, необходимые для того, чтобы заставить Equinox Aspects работать, потому что он вводит требуемый пакет/реэкспорт или импортный пакет на AspectJ RT в сплетенном комплекте. Эта зависимость должна быть динамически добавлена и рекомендована вне пакета.
Посмотрите ProxyWeavingHook из прокси-модуля Apache Aries. Он использует библиотеку ASM напрямую, чтобы изменить байт-код так на более низкий уровень.
WeavingAdaptor ожидает, что ваш WeavingClassLoader будет получен из URLClassLoader, поэтому оба доступных конструктора в основном делают то же самое в конце. Оформить заказ http://www.slideshare.net/mfrancis/bytecode-weaving, чтобы узнать, как BundleWiring можно использовать для получения доступа к URL-адресам класса. Вы можете добавить пакеты времени исполнения AspectJ в wovenClass.getDynamic'Imports(), чтобы избежать прямых ссылок AspectJ. BundleWiring - это также способ предоставить URL-адреса AspectJ для WeavingAdaptor.
Я думаю, что нет способа поддерживать новые классы, исходящие из acceptClass, потому что переплетение говорит о том, что динамический импорт может использоваться только внутри метода переплетения.