java Spring Framework 和其他 IoC 容器的内部结构

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/230084/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 11:31:46  来源:igfitidea点击:

Internals of Spring Framework and other IoC containers

javaspringjvminternals

提问by Miguel Ping

I've been using spring for some time, but I always wondered how does it work, more specifically, how do they load and weave beans/classes marked only with an interface or @annotation.

我已经使用 spring 一段时间了,但我一直想知道它是如何工作的,更具体地说,它们如何加载和编织仅用接口或@annotation标记的 bean/类。

For the xml declarations, it's easy to see how spring preprocesses my beans (they are declared in the xml context that spring reads), but for the classes marked only with annotations, I can't see how that works, since I don't pass any agent to the jvm or so.

对于 xml 声明,很容易看出 spring 如何预处理我的 bean(它们在 spring 读取的 xml 上下文中声明),但对于仅用注释标记的类,我看不到它是如何工作的,因为我没有将任何代理传递给 jvm 左右。

I believe there is some Java/JVM hook that allows you to preprocess classes by some sort of criteria, but I wasn't able to found out anything on the docs.

我相信有一些 Java/JVM 钩子可以让你按照某种标准预处理类,但我无法在文档中找到任何东西。

Can someone point me to some docs? Is this related to the java.lang.instrument.ClassFileTransformerAPI?

有人可以指点我一些文档吗?这是否与java.lang.instrument.ClassFileTransformerAPI 有关?

回答by Jevgeni Kabanov

Actually by default Spring does not do any bytecode postprocessing neither for XML-, nor annotation-configured beans. Instead relevant beans are wrapped into dynamic proxies (see e.g. java.lang.reflect.Proxyin the Java SDK). Dynamic proxies wrap the actual objects you use and intercept method calls, allowing to apply AOP advices. The difference is that proxies are essentially new artificial classes created by the framework, whereas weaving/bytecode postprocessing changes the existing ones. The latter is impossible without using the Instrumentation API you mentioned.

实际上默认情况下,Spring 不会对 XML 和注解配置的 bean 进行任何字节码后处理。相反,相关 bean 被包装到动态代理中(参见例如 java.lang.reflect.Proxy在 Java SDK 中)。动态代理包装您使用的实际对象并拦截方法调用,允许应用 AOP 建议。不同之处在于代理本质上是由框架创建的新人工类,而编织/字节码后处理更改了现有的类。如果不使用您提到的 Instrumentation API,后者是不可能的。

As for the annotations, the implementation of <context:component-scan>tag will scan the classpath for all classes with the Spring annotations and create Spring metadata placeholders for them. After that they are treated as if they were configured via XML (or to be more specific both are treated the same).

至于注解,<context:component-scan>标签的实现将扫描所有带有 Spring 注解的类的类路径,并为它们创建 Spring 元数据占位符。之后,它们被视为通过 XML 配置(或者更具体地说,两者被视为相同)。

Although Spring doesn't do bytecode postprocessing itself you can configure the AspectJ weaving agent that should work just fine with Spring, if proxies do not satisfy you.

尽管 Spring 本身不进行字节码后处理,但您可以配置 AspectJ 编织代理,如果代理不满足您,它应该可以与 Spring 一起正常工作。