简体   繁体   English

您如何确定 CLASS 是否是 spring 代理?

[英]How do you figure out whether a CLASS is a spring proxy?

In a nutshell简而言之

In the AopUtils , we haveAopUtils中,我们有

    /**
     * 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.

相关问题 你怎么知道哪个线程会先运行? - How do you figure out which thread will run first? 你如何找出基数排序的数字 - how do you figure out the digit for radix sort 我如何确定哪个类被执行为主类? - How do I figure out which class was executed as the main class? 根据教授需要弄清楚如何操纵变异子以找出一个类,我对此感到困惑 - need to figure out how to manipulate the mutator to figure out a class according to professor, I am confusd on how to do that 无法弄清楚如何使SWIG / Java强制一个代理类来实现一个接口 - can't figure out how to make SWIG/Java force a proxy class to implement an interface 春季批处理-交易失败-我如何找出问题所在? - Spring-batch - transactions out of kilter - how do I figure out what's wrong? Spring集成-如何确定处理已完成 - Spring integration - how to figure out that processing is finished 您如何找出逐字搜索的Big O和Big Omega? - How do you figure out Big O and Big Omega of a Septenary Search? 您如何指定/确定运行胖 jar 所需的最低 JDK? - How do you specify/figure out which minimum JDK is required for running the fat jar? 您如何用Eclipse找出哪个JAR依赖哪个JAR? - How do you figure out with Eclipse which JARs depend on which one?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM