作为开源生命周期框架API提供商,我想尽量以隐式方式隐藏内部设计以提供生命周期API,这样可以为API客户端带来更多便利。
预计将避免对Core Java应用程序和Java EE应用程序进行配置,但实际情况是我使用java命令-javaagent:$ {path} /Lifecycle.jar选项在类加载时启用我自己的ClassFileTransformer时间。
经过一些搜索后,发现了一些不明确的方向。我需要一些Java Guy来总结和指导我们。
与指定的运行时环境集成,例如Glassfish的ByteCodePreprocessor,它具有以下执行字节代码转换的方法:
public byte[] preprocess(String classname, byte[] classBytes);
我对这些方向的困惑:
(BTW Lifecycle API将遵循元驱动的风格,与JPA非常接近,没有EntityManager接口,现在大多数只是Annotations和CallbackContext接口以及LifecycleEvent接口。)
答案 0 :(得分:2)
嗯,我能想到的唯一其他方法是使用自定义类加载器,您可以在运行时注册。这就是像Powermock这样的框架如何解决这些问题。但是,这也需要一些设置,但可以以编程方式完成。
只要您的框架具有明确定义的入口点,并且只要所有代码都在您的应用程序中运行,您就可以应用自定义类加载器,它可以检测所有已加载的类。
但是,这对已经加载的类不起作用。 (您可以打破父级第一个patern,但这可能会在框架外部的实例上引发ClassCastException
。)
避免这种情况需要覆盖同样详细的系统类加载器。为了完整起见,这里是ClassLoader.getSystemClassLoader
的javadoc的摘录:
如果在此时定义了系统属性“java.system.class.loader” 首先调用方法,然后取该属性的值 将作为系统类加载器返回的类的名称。 该类使用默认的系统类加载器加载并且必须 定义一个公共构造函数,它接受一个类型的参数 ClassLoader,用作委托父级。一个例子是 然后使用此构造函数创建默认系统类 loader作为参数。生成的类加载器定义为 系统类加载器。
在这个自定义类加载器中,您可以随时返回已检测的类。
difference between agentmain
and premain
是在将代理附加到正在运行的JVM(via the attach API)时调用前者,而如果在JVM启动时在命令行上指定了代理,则调用后者。在运行时注册代理可能实际上是一个解决方案。我链接的博客条目提供了很好的描述。