【问题标题】:conditional beans using spring使用spring的条件bean
【发布时间】:2011-03-09 15:22:51
【问题描述】:

我正在尝试编写一个ValidatorFactory,它将根据其类型为我提供一个验证器

public Validator getNewValidator(ValidatorType type){

    switch:
         case a : new Validator1();
         break;
          case b : new Validator2();
        break;

}

我想用spring xml beans定义写

我可以使用方法注入,但它只会让我创建一个对象,而方法确实可以

不接受任何参数。

我不想使用FactoryBean.. 我只是想看看我们是否可以使用 spring xml 来做到这一点

bean 定义。

【问题讨论】:

  • 你为什么不想使用FactoryBean?
  • 没有这样的理由..我只是想知道有没有办法创建条件bean..只是出于好奇
  • 这正是FactoryBean 的用途。不要打它:)
  • 我只是在寻找一个答案,使用spring xml bean定义是否可行

标签: java spring dependency-injection


【解决方案1】:

您可以使用纯 xml 进行条件 bean 注入。 “ref”属性可以由属性文件中的属性值触发,从而根据属性值创建条件 bean。此功能未记录在案,但效果很好。

<bean id="validatorFactory" class="ValidatorFactory">
<property name="validator" ref="${validatorType}" />
</bean>

<bean id="validatorTypeOne" class="Validator1" lazy-init="true" />
<bean id="validatorTypeTwo" class="Validator2" lazy-init="true" />

属性文件的内容是:

validatorType=validatorTypeOne

要在 xml 中使用属性文件,只需将此上下文添加到 spring 配置的顶部

<context:property-placeholder location="classpath:app.properties" />

【讨论】:

  • 只需要更多解释一下如何在 XML 代码中执行 validatorType=validatorTypeOne 吗?
  • validatorType=validatorTypeOne 是属性文件中的内容,语法 ${validatorType} 扩展为属性的值,在本例中为:validatorTypeOne。由于 this 指向 bean 引用 id,因此将创建 Validator1 类的实例并将其分配给 ValidatorFactory 中的属性。明白了吗?
  • 不,我对validatorType=validatorTypeOne这句话有点困惑。如果我需要它是 validatorTypeTwo 怎么办?而且我在 ref="${validatorType}" 上也遇到了语法错误。我需要一些关于这个 ref 的参考,以便我能清楚地理解它。
  • 请谨慎使用任何使用 SmartLifecycle 的 bean。详情请见this thread
【解决方案2】:

对于复杂的情况(比公开的更复杂),Spring JavaConfig 可能是您的朋友。

【讨论】:

  • 在否决我的答案之前,请检查其日期。 Spring JavaConfig 在 2010 年还不是很普及。
【解决方案3】:

如果您使用注释(@Autowired@Qualifier 等)而不是 xml,则无法使条件 bean 工作(至少在当前版本 3 中)。这是因为@Qualifier 不支持表达式

@Qualifier(value="${validatorType}")

更多信息在https://stackoverflow.com/a/7813228/418439

【讨论】:

    【解决方案4】:

    我的要求略有不同。就我而言,我想在生产中使用编码密码,但在开发中使用纯文本。另外,我无权访问父 bean parentEncoder。这就是我设法实现这一目标的方式:

    <bean id="plainTextPassword" class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder"/>
    <bean id="shaPassword" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
        <constructor-arg type="int" value="256"/>
    </bean> 
    
    <bean id="parentEncoder" class="org.springframework.aop.framework.ProxyFactoryBean"> 
      <property name="targetSource"> 
        <bean class="org.springframework.aop.target.HotSwappableTargetSource"> 
          <constructor-arg ref="${password.encoding}Password"/> 
        </bean> 
      </property> 
    </bean>
    

    当然,我在属性文件中定义了password.encoding,可能的值为shaplainText

    【讨论】:

      【解决方案5】:

      你应该可以这样做:

      <bean id="myValidator" factory-bean="validatorFactory" factory-method="getNewValidator" scope="prototype">
          <constructor-arg><ref bean="validatorType"/></constructor-arg>
      </bean>
      
      <bean id="validatorType" ... />
      

      当然,它在下面使用了一个自动配置的FactoryBean,但你避免了代码中的任何 Spring 依赖。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-11
        • 2015-07-02
        • 1970-01-01
        • 2018-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多