首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止Spring在上下文刷新时实例化原型作用域bean?

如何防止Spring在上下文刷新时实例化原型作用域bean?
EN

Stack Overflow用户
提问于 2011-12-17 18:33:25
回答 2查看 5.2K关注 0票数 4

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

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

我看到的是,当应用程序上下文刷新时,它尝试实例化这些原型,这似乎与您希望原型所做的完全相反。它们是模板,而不是实际的实例。为了解决这个问题,我一直在用伪造的ctor值配置原型,因此这些伪bean实例被实例化,我只需在后面的代码中过滤掉创建的MBeans。

我的问题是,如何将应用程序上下文配置为注册--这些原型bean定义,而不是实例化定义,直到我进行getBean调用?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-17 18:42:44

更新:

这个问题比我最初想的要复杂一些。实际上,懒惰是原型范围内的bean的默认行为。我挖了一点,我设法重现了你的问题,并找到了解决办法。那么问题是什么呢?

您可能启用了<aop:scoped-proxy/>或(@ComponentScan(scopedProxy=...)等效)。在上下文刷新期间,Spring用作用域代理包装原型bean (ClosedMetricSubscriberFeed)。它使用类代理,因为(a)选择了类代理,或者(b)类没有接口。

基于类的代理基本上是bean的CGLIB子类,它必须调用基类的构造函数(由于JVM规则)。而CGLIB生成的类总是调用no-arg构造函数。

我知道这听起来很复杂,你可以这样做:

  1. 禁用<aop:scoped-proxy/>。简单得不得了。
  2. 提供一个虚拟的无arg构造函数,并在以防万一的情况下放弃它。不幸的是,您将不得不发现这样的虚假实例的男子。请注意,在本例中,类的类型为:。
  3. 从类中提取接口,并为作用域代理使用接口:

代码语言:javascript
复制
@Scope(
  value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,
  proxyMode = ScopedProxyMode.INTERFACES)

旧的答案:

使用延迟初始化和@Lazy注释或lazy-init="true" (参见参考文档中的4.4.4延迟初始化bean )配置属性。

代码语言:javascript
复制
<bean id="proto" class="MyPrototype" scope="prototype" lazy-init="true"/>

或者:

代码语言:javascript
复制
@Service
@Scope("prototype")
@Lazy
public class MyPrototype {/*...*/}
票数 7
EN

Stack Overflow用户

发布于 2013-01-08 21:56:04

我使用了一个私有的、不推荐的、非arg构造函数,它抛出一个IllegalStateException。上下文加载良好,带有构造函数args的getBean()运行良好,没有args的getBean()抛出异常。

代码语言:javascript
复制
package a;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("myCommand")
@Scope("prototype")
public class Command {
  final protected String name;

  @Deprecated
  private Command() {throw new IllegalStateException("Only for Spring"); }

  public Command(String name) {
    super();
    this.name = name;
  }

  @Override
  public String toString() {
    return "Command [name=" + name + "]";
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8546988

复制
相关文章

相似问题

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