Java OSGi编织钩示例
有人有使用OSGi4.3+编织钩子服务的例子吗?那么AspectJ、ASM和JavaAssist呢?有人真的在用OSGi编织钩吗 OSGi Core 5.0.0第56.2节中的示例只是省略了实际的编织,并说“最终的编织留给读者作为练习” 我的目标是:Java OSGi编织钩示例,java,osgi,aop,aspectj,load-time-weaving,Java,Osgi,Aop,Aspectj,Load Time Weaving,有人有使用OSGi4.3+编织钩子服务的例子吗?那么AspectJ、ASM和JavaAssist呢?有人真的在用OSGi编织钩吗 OSGi Core 5.0.0第56.2节中的示例只是省略了实际的编织,并说“最终的编织留给读者作为练习” 我的目标是: 创建可以放置在字段(基本体或对象)上的批注(@MyAnnotation) 创建org.osgi.framework.hooks.weaving.WeavingHook以使用该注释编织类 在对带有该注释的字段进行任何修改时,使用加载时编织到切入点 已
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
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
}
}
public class MyTestClass {
@MyAnnotation
private int myField;
public void doSomething() {
//do stuff with myField
}
}
MyWeavingHook.java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
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
}
}
public class MyTestClass {
@MyAnnotation
private int myField;
public void doSomething() {
//do stuff with myField
}
}
MyAspect.aj
privileged aspect MyAspect {
after() : set(* *) && @annotation(MyAnnotation) {
//send EventAdmin event
}
}
MyTestClass.java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
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
}
}
public class MyTestClass {
@MyAnnotation
private int myField;
public void doSomething() {
//do stuff with myField
}
}
我可以使用SpringAOP,但我希望它适用于任何包,而不仅仅是通过Spring或Blueprint实例化的bean。另外,Equinox编织似乎还没有使用OSGi编织钩子规范,我不想被束缚在Equinox上。如果其他东西工作得更好,我可以放弃AspectJ
提及类似问题:
更新:
最终的结果是我使用了Equinox Aspects并将其安装到Karaf中。是3个捆绑包、一个库和一个系统属性。我将使用它,直到他们将它更新为我们的OSGi编织,或者我编写自己的OSGi编织钩子来使用类似于Equinox方面的AspectJ代码。我不喜欢让Equinox方面工作所需的编织指标,因为它在要编织的捆绑包中引入了一个require bundle/reexport或AspectJ RT上的导入包。此依赖项应在捆绑包之外动态添加和建议。查看ApacheAries的代理模块。它直接使用ASM库修改字节码,使其级别更低 WeavingAdapter希望您的WeavingClassLoader是从URLClassLoader派生的,因此两个可用的构造函数最终基本上做相同的事情。签出以查看如何利用bundlewing来访问类路径URL。您可以将AspectJ运行时包添加到wovenClass.getDynamic'Imports()中,以避免直接引用AspectJ。BundleWiring也是为WeavingAdapter提供AspectJ URL的一种方式
我认为无法支持来自acceptClass的新类,因为编织钩子声明只有在编织方法内部才能使用动态导入。对于OSGi编织钩子,您会得到需要修改的类的字节[]。您不能尝试加载变异字节[]。这将由OSGi框架在调用所有编织钩子后完成。@bhargrave是的,规范是这么说的。问题是,哪些框架或库与OSGi兼容,并且很容易在WeavingHook.weave()方法中使用,我可以用它修改原始的类byte[]。。。有人真的这样做过吗?我想到了ASM或BCEL。@bhargrave好吧,这两个都列在我的问题中(BCEL通过aspectj间接列出)。在详细考虑了这一点之后,我认为我需要aspectj的强大功能,但是通过aspectj源代码来看,它并不支持osgi。我看到的唯一可用的框架是equinox方面。修改它以使用OSGi编织钩子而不是equinox扩展似乎比围绕aspectj编写自己的适配器工作量要少。您的答案是唯一的,也是合理的答案。最终的结果是我使用了Equinox Aspects并将其安装到Karaf中。是3个捆绑包、一个库和一个系统属性。我将使用它,直到他们将它更新为我们的OSGi编织,或者我编写自己的OSGi编织钩子来使用类似于Equinox方面的AspectJ代码。我不喜欢让Equinox方面工作所需的编织指标,因为它在要编织的捆绑包中引入了一个require bundle/reexport或AspectJ RT上的导入包。此依赖项应在捆绑包之外动态添加和通知。