Announcement Announcement Module
Collapse
No announcement yet.
Is it possible to redefine the way bean names are resolved? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Is it possible to redefine the way bean names are resolved?

    Hi,

    I wonder if there is a way to redefine the way bean names are resolved without rewriting Spring classes? Is there a way to plug your custom 'bean resolver' or probably custom application context? The goal is to be able to use bean name compounded of two parts: 'bean factory bean id' and 'bean name' within that factory. For example:

    Code:
    classpath:com/artilekt/webwork/action-beans.xml
    <beans>
      <bean id="com.artilekt.webwork.SimpleWebWorkEmailer" class="com.artilekt.modules.webwork.WebWorkEmailer">
        <property name="emailDispatcher" ref="emailDispatcher"/>
        <property name="messageClassName" value="com.artilekt.modules.jetmailer.model.Message"/>
        <property name="resultFactory">
          <bean class="com.artilekt.modules.webwork.impl.ResultFactoryImpl"/>
        </property>
      </bean>
    
     <alias name="com.artilekt.modules.jetmailer#simpleEmailDispatcher" alias="emailDispatcher"/>
    </beans>
    
    classpath:com/artilekt/modules/jetmailer/beanRefFactory.xml
    <beans>
      <bean id="com.artilekt.modules.jetmailer" lazy-init="true"
            class="org.springframework.context.support.ClassPathXmlApplicationContext">
        <constructor-arg>
          <list>
            <value>com/artilekt/modules/jetmailer/beans.xml</value>
          </list>
        </constructor-arg>
      </bean>
    </beans>
    
    classpath:com/artilekt/modules/jetmailer/beans.xml
    <beans>
      <bean id="simpleEmailDispatcher" class="com.artilekt.modules.jetmailer.EmailDispatcher$Emailer">
        <property name="mailSender" ref="mailSender"/>
      </bean>
    
    ....
    </beans>
    So, basically, is it possible to override the way how Spring would resolve "com.artilekt.modules.jetmailer#simpleEmailDispatc her" bean name, so that it will resolve 'simpleEmailDispatcher' name against 'com.artilekt.modules.jetmailer' application context bean.

    The way I'm achieving this right now is quite lenghty:
    Code:
    <beans>
      <bean id="com.artilekt.webwork.SimpleWebWorkEmailer" class="com.artilekt.modules.webwork.WebWorkEmailer">
        <property name="emailDispatcher" ref="emailDispatcher"/>
        <property name="messageClassName" value="com.artilekt.modules.jetmailer.model.Message"/>
        <property name="resultFactory">
          <bean class="com.artilekt.modules.webwork.impl.ResultFactoryImpl"/>
        </property>
      </bean>
    
      <bean id="emailDispatcher" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="com.artilekt.modules.jetmailer"/>
        <property name="targetMethod" value="getBean"/>
        <property name="arguments">
          <list>
            <value>simpleEmailDispatcher</value>
          </list>
        </property>
      </bean>
    
    </beans>
    That is, by actually calling 'getBean' method on the factory. Ideally I'm looking for a way to drop in a 'preprocessor' bean, which would redefine Spring bean name resolution mechanism, smth like:

    Code:
    <beans>
      <bean id="beanNameResolutionConfigurer" class="com.artilekt.spring.BeanNameResolutionConfigurer">
        <property name="delimeter" value="#"/>
      </bean>
    
      <bean id="com.artilekt.webwork.SimpleWebWorkEmailer" class="com.artilekt.modules.webwork.WebWorkEmailer">
        <property name="emailDispatcher" ref="emailDispatcher"/>
        <property name="messageClassName" value="com.artilekt.modules.jetmailer.model.Message"/>
        <property name="resultFactory">
          <bean class="com.artilekt.modules.webwork.impl.ResultFactoryImpl"/>
        </property>
      </bean>
    
      <alias name="com.artilekt.modules.jetmailer#simpleEmailDispatcher" alias="emailDispatcher"/>
    </beans>
    Sorry for a lenghty email. Thanks.

    Vlad

    PS: this question is related to some degree to a posting in 'architecture' group: http://forum.springframework.org/showthread.php?t=29389

  • #2
    BeanDefinitionValueResolver: any way to override beanFactory? (AOP?..)

    As a followup for the question above, I've narrowed down the search to BeanDefinitionValueResolver.resolveValueIfNecessar y method. But it seems to be the dead end. The thing that I need to do is to redefine 'beanFactory' field, against which the bean name is resolved (beanFactory.createBean), depending on the bean name, ie,

    - parse 'beanName' and
    - if it contains 'beanFactory' id,
    - lookup THAT factory in any of the available contexts and
    - resolve bean name against THAT factory

    BeanFactory passed on BeanDefinitionValueResolver initalization is 'hardcoded' to the beanFactory which creates the BeanDefinitionValueResolver.

    Is it possible to use Spring AOP for this? Would it be 'safe'?

    The only other solution I thought of so far is to use BeanFactoryPostProcessor to 'inject' MethodInvokingFactoryBean beans (basically, to do the same thing that is done right now in xml config file, but transparently to the user).

    Thanks!

    Vlad

    Comment

    Working...
    X