我在Spring描述符中使用原型作用域bean定义来配置默认属性(这些bean具有许多属性),然后使用getBean(beanName, ctorArgs[])调用应用程序上下文来创建实例。
bean定义需要2-3个构造函数参数,这些参数提供用于JMX、ObjectName等的键属性等的逻辑上唯一的键。此外,构造函数参数被写入的变量是最终的。
我看到的是,当应用程序上下文刷新时,它尝试实例化这些原型,这似乎与您希望原型所做的完全相反。它们是模板,而不是实际的实例。为了解决这个问题,我一直在用伪造的ctor值配置原型,因此这些伪bean实例被实例化,我只需在后面的代码中过滤掉创建的MBeans。
我的问题是,如何将应用程序上下文配置为注册--这些原型bean定义,而不是实例化定义,直到我进行getBean调用?
发布于 2011-12-17 18:42:44
更新:
这个问题比我最初想的要复杂一些。实际上,懒惰是原型范围内的bean的默认行为。我挖了一点,我设法重现了你的问题,并找到了解决办法。那么问题是什么呢?
您可能启用了<aop:scoped-proxy/>或(@ComponentScan(scopedProxy=...)等效)。在上下文刷新期间,Spring用作用域代理包装原型bean (ClosedMetricSubscriberFeed)。它使用类代理,因为(a)选择了类代理,或者(b)类没有接口。
基于类的代理基本上是bean的CGLIB子类,它必须调用基类的构造函数(由于JVM规则)。而CGLIB生成的类总是调用no-arg构造函数。
我知道这听起来很复杂,你可以这样做:
<aop:scoped-proxy/>。简单得不得了。。
@Scope(
value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,
proxyMode = ScopedProxyMode.INTERFACES)旧的答案:
使用延迟初始化和@Lazy注释或lazy-init="true" (参见参考文档中的4.4.4延迟初始化bean )配置属性。
<bean id="proto" class="MyPrototype" scope="prototype" lazy-init="true"/>或者:
@Service
@Scope("prototype")
@Lazy
public class MyPrototype {/*...*/}发布于 2013-01-08 21:56:04
我使用了一个私有的、不推荐的、非arg构造函数,它抛出一个IllegalStateException。上下文加载良好,带有构造函数args的getBean()运行良好,没有args的getBean()抛出异常。
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 + "]";
}
}https://stackoverflow.com/questions/8546988
复制相似问题