2010-03-26 17 views
60

¿Es posible desde Spring inyectar el resultado de llamar a un método en un ref bean?¿Es posible desde Spring inyectar el resultado de llamar a un método en un ref bean?

Estoy tratando de refactorizar un código cortado/pegado de dos proyectos separados en una clase común. En uno de los proyectos, el código vive en una clase a la que llamaré "MyClient" que está siendo instanciada desde Spring. Se inyecta con otra clase de instancia de primavera "MyRegistry", luego la clase MyClient usa esa clase para buscar un punto final. Todo lo que realmente necesito es la cadena de punto final en mi clase refactorizada, que se puede inicializar a través de un Setter. Realmente no puedo tener una dependencia en MyRegistry de MyClient en el código modificado.

Por lo tanto, mi pregunta es esta ... ¿hay alguna manera de que pueda inyectar la cadena de punto final de la primavera que se buscó en la clase MyRegistry. Por lo tanto, tengo actualmente:

<bean id="registryService" class="foo.MyRegistry"> 
...properties set etc... 
</bean> 

<bean id="MyClient" class="foo.MyClient"> 
    <property name="registry" ref="registryService"/> 
</bean> 

Pero me gustaría tener (y sé que esto es la sintaxis de la primavera imaginaria)

<bean id="MyClient" class="foo.MyClient"> 
    <property name="endPoint" value="registryService.getEndPoint('bar')"/> 
</bean> 

donde MyRegistry tendrá un método getEndPoint (Stirng endPointName)

Espero que tenga sentido desde el punto de vista de lo que estoy tratando de lograr. ¡Por favor avíseme si algo como esto es posible en Spring!

Respuesta

38

La solución mejor es utilizar lenguaje de expresión de Primavera de 3 como se describe por @ ChssPly76, pero si usted está utilizando una versión anterior de la primavera, es casi tan fácil:

<bean id="MyClient" class="foo.MyClient"> 
    <property name="endPoint"> 
     <bean factory-bean="registryService" factory-method="getEndPoint"> 
     <constructor-arg value="bar"/> 
     </bean> 
    </property> 
</bean> 
+1

Muy genial, y un poco tortuoso. Estamos usando Spring 2.5.6 aquí, así que intentaré utilizar esta técnica. Veo lo que estás haciendo ahora ... tratas el método getEndPoint() como un método de fábrica en registryService - la clase "construida en fábrica" ​​es una cadena simple que representa el endPoint. ¡Muy genial! ¡Espero que esto funcione! –

+3

"Devious" de hecho, ¿cómo te atreves :) Esto es exactamente cómo 'factory-bean' y' factory-method' se supone que se utilizarán, te lo haré saber :) – skaffman

98

Es posible en la primavera de 3,0 a través de Spring Expression Language:

<bean id="registryService" class="foo.MyRegistry"> 
...properties set etc... 
</bean> 

<bean id="MyClient" class="foo.MyClient"> 
    <property name="endPoint" value="#{registryService.getEndPoint('bar')}"/> 
</bean> 
+1

@ ChssPly76 Bienvenido, estás de vuelta –

+2

Esto es impresionante – jarandaf

+2

bastante impresionante y justo lo que nee ded !!!! – nterry

2

O en 2.x Spring, mediante el uso de un BeanPostProcessor

Típicamente, post procesadores bean se utilizan para comprobar la validez de las propiedades de frijol o alterando las propiedades de los frijoles (lo que quieras) según los criterios particulares.

public class MyClientBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware { 

    private ApplicationContext applicationContext; 
    public void setApplicationContext(ApplicationContext applicationContext) { 
     this.applicationContext = applicationContext; 
    } 

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
     return bean; 
    } 

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
     if((bean instanceof MyClient)) && (beanName.equals("MyClient"))) { 
      Myregistry registryService = (Myregistry) applicationContext.getBean("registryService"); 

      ((MyClient) bean).setEndPoint(registryService.getEndPoint("bar")); 
     } 

     return bean; 
    } 
} 

y registrar su BeanPostProcessor

<bean class="br.com.somthing.MyClientBeanPostProcessor"/> 
Cuestiones relacionadas