有人有使用 OSGi 4.3+ Weaving Hook Service 的例子吗?AspectJ、ASM、JavaAssist 怎么样?有人真的在使用 OSGi WeavingHooks 吗?
OSGi Core 5.0.0 第 56.2 节中的示例简单地省略了实际的编织,并说“最终的编织留给读者作为练习”。
我的目标是:
- 创建一个可以放在字段(基元或对象)上的注释(@MyAnnotation)。
- 创建一个 org.osgi.framework.hooks.weaving.WeavingHook 以使用该注释编织类
- 使用加载时编织来切入具有该注释的字段的任何修改
- 触发字段被修改的 EventAdmin 事件。
- 动态更新来自 WeavingHook 的包连接以连接到 EventAdmin 包。
我的问题主要是#3。
我目前正在尝试使用 AspectJ WeavingAdaptor进行编织,但是在将方面库放入其中时遇到问题,因为它期望构造函数中的java.net.URL[] aspectURLs是罐子或目录它可以在文件系统上找到,而不是捆绑包。另外,我不确定如何通过回调到 GeneratedClassHandler 的acceptClass(String name, bytes[])方法来处理编织器生成的任何新类。
也许 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
}
}
我的方面.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,但我希望它适用于任何包,而不仅仅是通过 Spring 或 Blueprint 实例化的 bean。此外,Equinox Weaving 似乎还没有使用 OSGi 编织钩子规范,我不想被 Equinox 束缚。如果其他方法效果更好,我可以毫无问题地废弃 AspectJ。
参考一个类似的问题:使用 OSGi 时是否可以进行字节码操作?
更新:
最终结果是我刚刚使用 Equinox Aspects 并将其安装到 Karaf 中。是 3 个捆绑包、一个库和一个系统属性。我会一直使用它,直到他们将它更新为我们的 OSGi 编织,或者我编写自己的 OSGi 编织钩子以使用类似于 Equinox Aspects 的 AspectJ 代码。我不喜欢让 Equinox Aspects 工作所需的编织指标,因为它在要编织的包中的 AspectJ RT 上引入了 require-bundle/reexport 或 import-package。应该在捆绑包之外动态添加和建议此依赖项。