我遇到了一篇关于AOP的文章,在那里提到Aspect编织可以在编译时,类加载时和运行时发生。
在java中,我可以想象,而不是理解编译时编程方面实际上会发生的方式。代理类在类编译过程中生成(在项目中启用了方面)。生成的字节码将具有代理代码。
但我仍然想知道在类加载时间编织和运行时编织期间究竟(实际)发生了什么。代理类是在加载类时生成的吗?方面库是否在.class(编译时)文件中添加任何编程指令以生成代理类?
答案 0 :(得分:6)
Spring AOP 实际上将Java Dynamic Proxies用于接口,如果需要,还使用 cglib 作为非接口类型。它只适用于Spring Beans。为所有与所谓的切入点匹配的方法自动生成代理。这是在布线期间完成的。
然而,AspectJ 不需要甚至不使用代理,它直接生成字节代码,编码到现有的字节代码中。 AspectJ功能更强大,可以做的不仅仅是方法拦截。
答案 1 :(得分:2)
不一定在编译时。在Java中,通过反射和类加载器,您可以在运行时以编程方式查看甚至或修改创建方法和类。
例如,
"hello".getClass().getMethod("substring", Integer.TYPE).invoke("my sharona", 3)
将返回“sharona”,从String实例中提取方法子字符串并将其应用于另一个对象。
使用自定义classloader,您可以定义从系统加载类的方式。这样,您就可以定义一个方法,该方法将被调用以加载(或生成!)类的字节码。您还可以使用系统类加载器加载类的字节码并进行检查。
这种技术被Mozilla Rhino广泛使用,它可以使用它将已编译的JavaScript加载为Java字节码以提高效率,或JavAssist,它允许您在运行时创建类,方法,字段和任何内容
JBoss或TomCat等应用程序服务器也使用反射来检查和操作代码,尤其是通过注释。
答案 2 :(得分:1)
不确定什么是运行时编织。在加载时编织中,代理拦截类加载并在将字节代码传递给类加载器之前修改它。
要查看其工作原理非常简单,例如使用AspectJ。您可以使用编译时编织和反汇编代码来确切了解它是如何工作的。还可以指示AspectJ在加载时编织期间将生成的类保存在磁盘上。