[英]How do you figure out whether a CLASS is a spring proxy?
In a nutshell简而言之
In the AopUtils
, we have在AopUtils
中,我们有
/**
* Check whether the given object is a JDK dynamic proxy or a CGLIB proxy.
* <p>This method additionally checks if the given object is an instance
* of {@link SpringProxy}.
* @param object the object to check
* @see #isJdkDynamicProxy
* @see #isCglibProxy
*/
public static boolean isAopProxy(@Nullable Object object) {
return (object instanceof SpringProxy && (Proxy.isProxyClass(object.getClass()) ||
object.getClass().getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)));
}
In now want to check whether a bean class is proxied without instantiating the bean (ie just with its class) in a BeanFactoryPostProcessor
.现在想检查一个 bean class 是否在没有在BeanFactoryPostProcessor
中实例化 bean(即仅使用其类)的情况下被代理。
I thought I could just "translate" above method:我以为我可以“翻译”上述方法:
private fun <T> isAopProxyClass(candidate: Class<T>): Boolean {
return SpringProxy::class.java.isAssignableFrom(candidate)
&& (
Proxy.isProxyClass(candidate)
|| candidate.name.contains(CGLIB_CLASS_SEPARATOR)
)
}
But this does not detect proxies because SpringProxy::class.java.isAssignableFrom(candidate)
is false
even for obviously proxied classes.但这不会检测到代理,因为SpringProxy::class.java.isAssignableFrom(candidate)
即使对于明显代理的类也是false
的。
How do I make this work?我该如何进行这项工作?
Full picture完整的图片
I'm in a BeanFactoryPostProcessor
and I need the un-proxied bean classes to access certain annotated methods by reflection.我在BeanFactoryPostProcessor
中,我需要未代理的 bean 类来通过反射访问某些带注释的方法。
Access happens in a lambda function that will first use the ApplicationContext
to retrieve the bean for the class.访问发生在 lambda function 中,它将首先使用ApplicationContext
来检索 class 的 bean。 The bean must not be forcibly instantiated in this BeanFactoryPostProcessor
(and in fact should throw an exception if it does because some beans are session-scoped).不得在此BeanFactoryPostProcessor
中强制实例化 bean(事实上,如果这样做应该抛出异常,因为某些 bean 是会话范围的)。
Interesting question.有趣的问题。 😀 😀
The three classes highlighted in your screenshot are CGLIB proxies but not AOP proxies.屏幕截图中突出显示的三个类是 CGLIB 代理,但不是AOP 代理。 Look at their class names: They are all Spring configuration classes.看它们的类名:都是Spring的配置类。 But that does not make them normal Spring proxies, especially not AOP proxies.但这并不能使它们成为普通的 Spring 代理,尤其是 AOP 代理。 For the difference between @Component
and @Configuration
, also with regard to proxying and self-invocation behaviour, please read my answer here .对于@Component
和@Configuration
之间的区别,以及代理和自调用行为,请在此处阅读我的回答。
Consequently, a Spring @Configuration
class also does not implement SpringProxy
like normal Spring proxies.因此,Spring @Configuration
类也不像普通的 Spring 代理那样实现SpringProxy
。
So basically your solution works just fine, no need to worry, as far as I can see.所以基本上你的解决方案工作得很好,不用担心,据我所知。
PS: I am a Java guy, not a Kotlin person. PS:我是 Java 人,不是 Kotlin 人。 So I re-implemented your code from the screenshot in Java, so I could debug into it and reproduce your situation.因此,我从 Java 屏幕截图中重新实现了您的代码,以便我可以对其进行调试并重现您的情况。 But even in Kotlin I would have had to re-type everything.但即使在 Kotlin 中,我也不得不重新输入所有内容。 Please next time publish the code as copyable text, not just as an image.下次请将代码发布为可复制的文本,而不仅仅是图像。
Update: If you check something like the content of更新:如果你检查类似的内容
beanClasses.stream()
.filter(aClass ->
aClass.getName().contains(CGLIB_CLASS_SEPARATOR) &&
aClass.getSuperclass().getAnnotation(Configuration.class) == null
)
.collect(Collectors.toList())
you should see an empty collection, whereas你应该看到一个空的集合,而
beanClasses.stream()
.filter(aClass ->
aClass.getName().contains(CGLIB_CLASS_SEPARATOR) &&
aClass.getSuperclass().getAnnotation(Configuration.class) != null
)
.collect(Collectors.toList())
should yield the same list of classes as simply应该产生与简单相同的类列表
beanClasses.stream()
.filter(aClass -> aClass.getName().contains(CGLIB_CLASS_SEPARATOR))
.collect(Collectors.toList())
Ie all remaining CGLIB proxies in beanClasses
should in fact be configurations, not normal Spring proxies.即beanClasses
所有剩余的 CGLIB 代理实际上应该是配置,而不是普通的 Spring 代理。
In now want to check whether a bean class is proxied without instantiating the bean (ie just with its class) in a BeanFactoryPostProcessor.现在想检查一个bean class 是否在没有在BeanFactoryPostProcessor 中实例化bean(即仅使用它的类)的情况下被代理。
This task seems impossible to me since there are 100500 ways to proxy bean at runtime (bean post processor, advice, etc).这个任务对我来说似乎是不可能的,因为有 100500 种方法可以在运行时代理 bean(bean 后处理器、建议等)。 Technically you can use random to decide whether to proxy some bean.从技术上讲,您可以使用 random 来决定是否代理某些 bean。 You can have two instances of a given class (eg with different qualifiers), one proxied, other not.您可以有两个给定 class 的实例(例如,使用不同的限定符),一个被代理,另一个没有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.