2008-11-21 12 views
49

Soy un usuario final de uno de los productos de mi empresa. No es muy adecuado para la integración en Spring, sin embargo, soy capaz de manejar el contexto y recuperar el bean requerido por su nombre. Sin embargo, aún me gustaría saber si es posible inyectar un frijol en esta clase, incluso si la clase no está administrada por Spring.Inyectar beans en una clase fuera del contexto administrado de Spring

Aclaración: la misma aplicación que está administrando el ciclo de vida de alguna clase MyClass, también está administrando el ciclo de vida del contexto de Spring. Spring no tiene ningún conocimiento de la instancia de MyClass, y me gustaría saber cómo proporcionar la instancia al contexto, pero no puedo crear la instancia en el contexto mismo.

+0

Aclare: ¿Desea inyectar el bean a través de Spring Configuration, Spring dinámicamente en tiempo de ejecución o mediante programación a través de un setter? –

+0

Cualquier método está bien. El punto es que la aplicación ha creado el objeto en el que quiero inyectar un bean, por lo que el objeto original no está gestionado por el contexto de Spring. –

+0

Además, considere usar un método de fábrica para poder colocar la clase en el contexto de la aplicación y configurarla como un bean Spring normal. Mira los documentos de referencia de primavera con respecto a las fábricas de frijoles. – cletus

Respuesta

50

Usted ca n hacer esto:

ApplicationContext ctx = ... 
YourClass someBeanNotCreatedBySpring = ... 
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(
    someBeanNotCreatedBySpring, 
    AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true); 

Puede utilizar @Autowired y así sucesivamente dentro YourClass para especificar los campos que se inyecta etc.

+0

Nunca tuve la oportunidad de probar esto, pero parece estar más cerca de lo que estaba buscando. Sería bueno darle un giro. –

+0

Esta [respuesta] (http://stackoverflow.com/a/129999/1370556) explica cómo obtener 'ApplicationContext' – lebolo

2

suponer que u tiene la siguiente cadena de dependencias:

A -> B -> C -> x -> Y -> Z

A, B, C están controlados primavera frijoles (construidos y administrados por marco de primavera) x, y son POJOs realmente simples que construyó su aplicación, sin asistencia de resorte

ahora si quiere eso y obtendrá una referencia a Z utilizando la primavera que necesita tener un 'manejar' al resorte ApplicationContext

Una forma de hacerlo es implementar la interfaz ApplicationContextAware. En este caso, sugeriría que A, B o C implementarán esta interfaz y almacenarán la referencia de applicationContext en un miembro estático.

por lo que permite tomar Clase C, por ejemplo:

class C implmenets ApplicationContextAware{ 
    public static ApplicationContex ac; 
    void setApplicationContext(ApplicationContext applicationContext) { 
       ac = applicationContext; 
    } 
............. 
} 

ahora, en la clase Y usted debe tener:

(Z)(C.ac.getBean("classZ")).doSomething() 

HTH - Yonatan

+0

¿Qué tal: xey no tiene dependencia de C, y deseo inyectar Z en x o y? Parece que tendría que usar la etiqueta @Comparable en el contexto de primavera, luego hacer un poco de tiempo de ejecución después del hecho. Hasta ahora no he logrado hacer que esto funcione, y agrega trabajo adicional. Buscando una manera más fácil. –

+0

Esto es francamente feo – fnt

+0

Está configurando la 'ca' (que es estática) del método 'setApplicationContext' que no es estático. Idealmente, los campos estáticos solo se actualizan a partir de métodos estáticos sincronizados. De lo contrario, esto podría conducir fácilmente a errores si hay varias instancias de clase y/o múltiples hilos en juego. – vadim

1

la búsqueda sin fin de combinaciones de Autowire inyectar frijol resorte en POJO applicationcontextaware beanaware etc círculos a mi vuelta aquí, pero esto no me proporcionó una solución lo suficientemente completa.

Esta es una implementación/tutorial mucho mejor de esta IMO: Espero que ayude a todos los que finalmente me hayan ayudado.

Accessing Spring Beans from outside Spring Context

1

Una forma de llevar un grano en la primavera a pesar de su fabricación es externa es el uso de una clase de ayuda marcado como un grano @Configuration que tiene un método (marcado con @Bean) que en realidad hace la instancia y la devuelve a través de Spring (que hace su inyección de propiedad y generación proxy en ese punto).

No estoy seguro del alcance que necesita; con prototype, obtendrá un frijol nuevo en cada lugar.

@Configuration 
public class FooBarMaker { 
    @Bean(autowire = Autowire.BY_TYPE) 
    @Scope("prototype") 
    public FooBar makeAFooBar() { 
     // You probably need to do some more work in here, I imagine 
     return new FooBar(); 
    } 
} 

Puede inyectar las propiedades requeridas para la fabricación en el grano @Configuration. (Lo utilizo para crear instancias de una interfaz donde el nombre de la clase para crear una instancia se define en tiempo de ejecución.)

0

Si desea crear un objeto fuera el contexto de Primavera, y hacer que el objeto esté disponible para su inyección en otros beans que son en el contexto Spring, puede seguir los pasos en this article.

Básicamente, usted crea un contexto de aplicación padre e inserta su objeto externo en este contexto padre como singleton. Luego, crea el contexto principal de la aplicación (por ejemplo, desde archivos xml), con el contexto de la aplicación principal como su elemento principal.

Object externalObject = ... 
GenericApplicationContext parent = new StaticApplicationContext(); 
parent.getBeanFactory().registerSingleton("externalObject", externalObject); 
parent.refresh(); 
ApplicationContext appContext = new ClassPathXmlApplicationContext(... , parent); 
Cuestiones relacionadas