gpt4 book ai didi

spring - 如何防止 Spring 在上下文刷新时实例化原型(prototype)作用域 bean?

转载 作者:行者123 更新时间:2023-12-03 21:29:00 24 4
gpt4 key购买 nike

我在我的 Spring XML 描述符中使用原型(prototype)范围的 bean 定义来配置默认属性(这些 bean 有很多属性),然后我用 getBean(beanName, ctorArgs[]) 调用应用程序上下文。创建实例。

bean 定义需要 2-3 个构造函数参数,这些参数提供逻辑上唯一的键,用于 JMX ObjectName 的键属性等。等等。此外,构造函数参数写入的变量是最终的。

我看到的是,当应用程序上下文刷新时,它会尝试实例化这些原型(prototype),这似乎与您希望原型(prototype)做的完全相反。它们是模板,而不是实际实例。为了解决这个问题,我一直在用虚假的 ctor 值配置原型(prototype),以便实例化这些虚假的 bean 实例,并且稍后在代码中过滤掉创建的 MBean。

我的问题是,如何将应用程序上下文配置为 注册 这些原型(prototype) bean 定义,但不是 实例化 直到我制作 getBean称呼 ?

最佳答案

更新:
这个问题比我最初想象的要复杂一些。事实上,惰性是原型(prototype)范围 bean 的默认行为。我挖了一下,我设法重现了您的问题并找到了解决方案。那么问题是什么?
你可能有 <aop:scoped-proxy/>启用或(@ComponentScan(scopedProxy=...) 等效项)。在上下文刷新期间,Spring 使用作用域代理包装您的原型(prototype) bean (ClosedMetricSubscriberFeed)。它使用类代理是因为 (a) 选择了类代理或 (b) 该类没有接口(interface)。
基于类的代理基本上是 bean 的 CGLIB 子类,它必须调用(由于 JVM 规则)基类的构造函数。并且 CGLIB 生成的类总是调用无参数构造函数。
我知道这听起来很复杂,您可以这样做:

  • 禁用 <aop:scoped-proxy/> .就这样。
  • 提供一个虚拟的无参数构造函数并弃用它以防万一。不幸的是,您将不得不手动发现此类虚假实例。请注意,在这种情况下,该类的类型为:``。
  • 从您的类中提取一个接口(interface)并为作用域代理使用接口(interface):

  • .
    @Scope(
    value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,
    proxyMode = ScopedProxyMode.INTERFACES)

    老答案:
    使用带有 @Lazy 的延迟初始化注释或 lazy-init="true" (参见引用文档中的 4.4.4 Lazy-initialized beans)配置属性。
    <bean id="proto" class="MyPrototype" scope="prototype" lazy-init="true"/>
    或者:
    @Service
    @Scope("prototype")
    @Lazy
    public class MyPrototype {/*...*/}

    关于spring - 如何防止 Spring 在上下文刷新时实例化原型(prototype)作用域 bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8546988/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com