2011-09-08 28 views
7

Tengo una aplicación Grails que necesita ejecutar una estrategia que probablemente se intercambiará con el tiempo. Sé que Spring es la base de Grails, por lo que me preguntaba si tenía acceso al contenedor IoC de Spring para poder externalizar la dependencia real en un archivo xml (nota: nunca lo hice, solo sé de él, así que puedo estarlo). Echando de menos algo). Mi objetivo es ser capaz de hacer algo como lo siguiente:Grails Dependency Injection fuera de los servicios?

class SchemaUpdateService { 
public int calculateSomething(){ 
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 
IStrategy strat = (IStrategy) ctx.getBean("mystrat"); 
} 
} 

y asigne a la aplicación correspondiente en el archivo beans.xml. Supongo que esto es compatible con Grails. ¿Alguien tiene documentación sobre cómo funcionaría esto? ¿De verdad solo necesito la biblioteca Spring IoC y simplemente funcionará? ¡Gracias!

Respuesta

5

Usted define sus granos en resources.xml o resources.groovy. The grails documentation es muy claro acerca de cómo acceder al contexto de la aplicación Spring.

+0

Muchas gracias. Creo que cuando leí esto la primera vez no lo asimilé porque aún no tenía ningún contexto. ¡Lo aprecio! – skaz

+0

@skaz, mira las preguntas frecuentes en http://www.grails.org/FAQ, busca 'applicationContext' con tu navegador, también tiene algunas opciones. – hvgotcodes

+0

Gracias, lo aprecio. – skaz

4

Se puede acceder al contexto de aplicación de cualquier artefacto Griales usando

ApplicationContext ctx = grailsApplication.mainContext 

A continuación, puede utilizar este para recuperar lo que los granos que le interesa:

IStrategy strat = (IStrategy) ctx.getBean("mystrat") 

En las clases que no lo hacen tener acceso a grailsApplication, puede usar un ayudante como el siguiente para acceder al contexto de la aplicación y los frijoles en el mismo

class SpringUtils { 

    static getBean(String name) { 
     applicationContext.getBean(name) 
    } 

    static <T> T getBean(String name, Class<T> requiredType) { 
     applicationContext.getBean(name, requiredType) 
    } 

    static ApplicationContext getApplicationContext() { 
     ApplicationHolder.application.mainContext 
    } 
} 

Sin embargo, esto solo debería ser necesario si necesita recuperar diferentes implementaciones del mismo bean en tiempo de ejecución. Si el grano requerido es conocido en tiempo de compilación, simplemente conectar los granos juntos en resources.xml o resources.groovy

4

En primer lugar, se quiere definir su estrategia en su grails-app/conf/spring/resources.groovy:

beans = { 
    myStrat(com.yourcompany.StrategyImpl) { 
     someProperty = someValue 
    } 
} 

A continuación, sólo tiene que def la una propiedad con el mismo nombre en su servicio:

class SomeGrailsService { 
    def myStrat 

    def someMethod() { 
     return myStrat.doSomething() 
    } 
} 

En cualquier artefacto Grails (como los servicios y las clases de dominio), Griales dará automáticamente el myStrat propiedad el valor correcto. Pero no lo olvide, en una prueba unitaria tendrá que darle un valor manualmente ya que el auto-cableado no ocurre en las pruebas unitarias.

Fuera de un artefacto Grails, se puede usar algo como:

def myStrat = ApplicationHolder.application.mainContext.myStrat 

En Grails 2.0, Graeme y otros están deprecating el uso de las clases *Holder (como ApplicationHolder y ConfigurationHolder), así que estoy no estoy seguro de cuál sería el enfoque de Grails 2.0 ...

Cuestiones relacionadas