OSGi Core 5.0.0第56.2节中的例子简单地省去了实际的编织,并说“最后的编织作为练习留给读者”.
我的目标是:
>创建一个我可以放在字段(基元或对象)上的注释(@MyAnnotation).
>创建一个org.osgi.framework.hooks.weaving.WeavingHook编写具有该注释的类
>使用加载时编织来切换具有该注释的字段的任何修改
> fire EventAdmin事件,字段被修改.
>动态更新从WeavingHook到捆绑线束到EventAdmin捆绑包.
我的问题主要是#3.
我正在尝试使用AspectJ WeavingAdaptor进行编织,但是由于我们期望构造函数中的java.net.URL [] aspectURL可以是jars或目录它可以在文件系统上找到,而不是捆绑.另外,我不知道如何处理由编译器生成的任何新类,通过回调到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 } }
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,但是我希望这可以用于任何bundle,而不仅仅是通过Spring或Blueprint实例化的bean.此外,Equinox编织似乎没有使用OSGi编织钩规格,我不想被绑定到Equinox.如果其他工作效果更好,我没有问题.
参考类似的问题:Is it possible to do bytecode manipulation when using OSGi?
更新:
最终的结果是我刚刚使用Equinox Aspects并将其安装到Karaf.是3个捆绑包,一个库和一个系统属性.我会使用它,直到它们更新到我们OSGi编织,或者我编写自己的OSGi编织钩子来使用类似于Equinox Aspects的AspectJ代码.我不喜欢使Equinox Aspects工作所需的编织指示器,因为它在要编织的包中的AspectJ RT上引入了需求捆绑/重新输出或导入包.该依赖关系应该在捆绑包之外动态添加和建议.