是否有人有使用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是jar或目录它可以在文件系统上找到,而不是捆绑包。另外,我不知道如何通过回调的处理由韦弗产生的任何新类acceptClass(字符串名称,字节[])的方法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,但是我希望它适用于任何捆绑软件,而不仅仅是通过Spring或Blueprint实例化的bean。另外,Equinox Weaving似乎还没有使用OSGi编织钩规范,我也不想被Equinox束缚。如果有其他更好的方法,我可以毫无疑问地废弃AspectJ。
参考类似的问题:使用OSGi时是否可以进行字节码操作?https://stackoverflow.com/questions/563305/is-it-possible-to-do-bytecode-manipulation-when-using-osgi
更新:
最终结果是我只使用了Equinox Aspects,并将其安装到Karaf中。是3个包,一个库和一个系统属性。在他们将其更新到我们的OSGi编织或我编写自己的OSGi编织钩以使用类似于Equinox Aspects的AspectJ代码之前,我将一直使用它。我不喜欢使Equinox Aspects正常工作所需的编织指标,因为它在AspectJ RT上将要编织的捆绑软件中引入了要求捆绑/重新导出或导入包。应该在捆绑包之外动态添加并建议这种依赖关系。