首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何确定类是否是spring代理?

如何确定类是否是spring代理?
EN

Stack Overflow用户
提问于 2020-09-23 11:29:50
回答 2查看 1.3K关注 0票数 2

简单地说,

AopUtils中,我们有

代码语言:javascript
运行
复制
    /**
     * 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)));
    }

现在想要检查bean类是否在BeanFactoryPostProcessor中不实例化bean (也就是它的类)的情况下被代理。

我想我可以“翻译”上面的方法:

代码语言:javascript
运行
复制
    private fun <T> isAopProxyClass(candidate: Class<T>): Boolean {
        return SpringProxy::class.java.isAssignableFrom(candidate)
            && (
            Proxy.isProxyClass(candidate)
                || candidate.name.contains(CGLIB_CLASS_SEPARATOR)
            )
    }

但是这并不能检测代理,因为SpringProxy::class.java.isAssignableFrom(candidate)false,甚至对于明显的代理类也是如此。

我该怎么做呢?

全屏

我在一个BeanFactoryPostProcessor中,我需要未代理的bean类来通过反射访问某些带注释的方法。

访问发生在lambda函数中,该函数将首先使用ApplicationContext检索类的bean。这个bean不能在这个BeanFactoryPostProcessor中强制实例化(如果它强制实例化,那么它实际上应该抛出一个异常,因为有些bean是会话范围的)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-24 02:00:09

有趣的问题。

屏幕截图中突出显示的三个类是CGLIB代理,但不是 AOP代理。看看它们的类名:它们都是Spring配置类。但这并不能使它们成为普通的Spring代理,尤其是AOP代理。关于@Component@Configuration之间的区别,也是关于代理和自调用行为,请阅读my answer here

因此,Spring类也不像普通的Spring那样实现@Configuration

因此,据我所见,基本上您的解决方案工作得很好,不需要担心。

P.S.:我是爪哇人,不是科特林人。因此,我从Java的屏幕截图中重新实现了您的代码,这样我就可以调试到其中并再现您的情况。但即使在科特林,我也不得不重新打字。请下次将代码作为可复制的文本发布,而不仅仅是作为图像。

更新:如果您检查类似于

代码语言:javascript
运行
复制
beanClasses.stream()
  .filter(aClass -> 
    aClass.getName().contains(CGLIB_CLASS_SEPARATOR) && 
      aClass.getSuperclass().getAnnotation(Configuration.class) == null
  )
  .collect(Collectors.toList())

您应该看到一个空集合,而

代码语言:javascript
运行
复制
beanClasses.stream()
  .filter(aClass -> 
    aClass.getName().contains(CGLIB_CLASS_SEPARATOR) && 
      aClass.getSuperclass().getAnnotation(Configuration.class) != null
  )
  .collect(Collectors.toList())

应该产生与以下简单类相同的类列表

代码语言:javascript
运行
复制
beanClasses.stream()
  .filter(aClass -> aClass.getName().contains(CGLIB_CLASS_SEPARATOR))
  .collect(Collectors.toList())

也就是说,beanClasses中所有剩下的CGLIB代理实际上应该是配置,而不是普通的Spring代理。

票数 1
EN

Stack Overflow用户

发布于 2022-08-02 15:28:51

现在的

想要检查bean类是否被代理,而不实例化BeanFactoryPostProcessor中的bean (也就是它的类)。

这个任务在我看来是不可能的,因为在运行时有100500种代理bean的方法(bean后处理器、建议等)。从技术上讲,您可以使用随机的方式来决定是否代理某个bean。您可以拥有给定类的两个实例(例如,具有不同的限定符),一个代理,另一个没有。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64026990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档