【问题标题】:spring bean with dynamic constructor value具有动态构造函数值的spring bean
【发布时间】:2012-02-05 01:16:31
【问题描述】:

我需要创建一个没有构造函数参数的不完整对象。像这样的

Class A  {
  private final int timeOut
  public A(int timeout)
  {
     this.timeOut = timeout;
   }
 //...
}

我希望这个 Bean 由 Spring 管理,以便以后可以使用 Spring AOP。

<bean id="myBean" class="A" singleton="false">
</bean>

但是,我的 bean 需要超时才能作为动态值传递 - 有没有办法创建一个 Spring 托管 bean,并在构造函数中注入动态值?

【问题讨论】:

标签: java spring


【解决方案1】:

BeanFactory 有一个getBean(String name, Object... args) 方法,根据javadoc,它允许您指定用于覆盖bean 定义自己的参数的构造函数参数。因此,您可以在 beans 文件中放置一个默认值,然后在需要时指定“真实”运行时值,例如

<bean id="myBean" class="A" scope="prototype">
   <constructor-arg value="0"/> <!-- dummy value -->
</bean>

然后:

getBean("myBean", myTimeoutValue);

我自己没有尝试过,但应该可以。

附: scope="prototype" 现在比 singleton="false" 更可取,这是不推荐使用的语法 - 它更明确,但做同样的事情。

【讨论】:

  • 如何通过注解来实现...?我的意思是@Autowired @Parameter1(value="xxx", type="String")
  • @PatrickJeon 这对我来说看起来很有趣。但是,我似乎找不到任何支持这一点的文档,也不知道应该导入什么。 @Parameter1 无法识别。我收到了有关 Hibernate 和 JUnit 的建议,但似乎都不合适。任何指针将不胜感激。
  • 强烈建议不要在代码中使用 ApplicationContext 类中的 getBean(String name, Object... args)。 docs.spring.io/spring/docs/current/spring-framework-reference/…阅读“使用容器”章节的最后部分。
  • @VadimKirilchuk:它没有说“强烈不推荐”,它说的是“理想情况下”。在某些情况下使用getBean 是完全有效的。
  • 好吧,当你在你的类中使用 getBean 时,你会在你的类中引入直接的 spring 依赖,并开始使用 spring 作为服务定位器而不是 DI。在 spring 相关的类中使用 getBean 是可以的,比如自定义 BeanPostProcessorFactory 或类似的东西,但你应该避免在其他地方使用它。这就是为什么我说“非常不推荐”
【解决方案2】:

想到两个选项(没有双关语):


1.创建一个超时工厂,并将其用作构造函数参数。 您可以创建一个实现 FactoryBean 的 bean,它的工作是创建其他 bean。因此,如果你有一些东西可以生成用于加密的 salt,你可以让它从 getObject() 返回一个 EncryptionSalt 对象。在您的情况下,您想要生成整数。

这里是一个例子:http://www.java2s.com/Code/Java/Spring/SpringFactoryBeanDemo.htm


2。创建一个包含动态设置的 int 的超时 bean,并将其保持在“原型”状态,以便每次都创建它 EncryptionSalt 对象可以被声明为原型 bean,而不是去创建工厂的麻烦,所以当它被注入时,每次都会创建一个新对象。将逻辑放入构造函数或其他地方。


这在一定程度上取决于您希望超时实际是什么值。

【讨论】:

  • 我希望 timeout 是一个纯整数值。你能举出你在这里提到的两种方法的例子吗?
  • 我已经为你详细解答了。
【解决方案3】:

明确执行:

interface Bean {
    void setTimeout(int timeout);
}

class BeanImpl implements Bean {
    private int timeout;

    @Override
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }
    ...
}

<bean id="bean" class="BeanImpl" scope="prototype">
    ...
    <!-- Nothing about timeout here -->
    ...
</bean>

class Client {
    private Bean bean;
    public void setBean(Bean bean) {
        this.bean = bean;
    }
    ...
    public void methodThatUsesBean() {
        int timeout = calculateTimeout();
        bean.setTimeout(timeout);
        ...
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-07
    • 2017-03-09
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多