2010-09-28 25 views
94

Digamos que tenemos una clase:Cómo inyectar dependencias en un objeto autoejeado en Spring?

public class MyClass { 
    @Autowired private AnotherBean anotherBean; 
} 

Entonces creamos un objeto de esta clase (o algún otro marco han creado la instancia de esta clase).

MyClass obj = new MyClass(); 

¿Es posible todavía inyectar las dependencias? Algo así como:

applicationContext.injectDependencies(obj); 

(creo que Google Guice tiene algo como esto)

Respuesta

141

Puede hacerlo utilizando el método autowireBean() de AutowireCapableBeanFactory. Le pasas un objeto arbitrario, y Spring lo tratará como algo creado por sí mismo, y aplicará los diversos bits y piezas de autowiring.

Para controlar la AutowireCapableBeanFactory, simplemente Autowire que:

private @Autowired AutowireCapableBeanFactory beanFactory; 

public void doStuff() { 
    MyBean obj = new MyBean(); 
    beanFactory.autowireBean(obj); 
    // obj will now have its dependencies autowired. 
} 
+0

Buena respuesta (+1). También hay un segundo método en el que puede influir en cómo se realiza el autoenvío: http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/config/AutowireCapableBeanFactory.html# autowireBeanProperties% 28java.lang.Object,% 20int,% 20boolean% 29 –

+0

Pero, ¿qué ocurre si tengo dos objetos y primero me autoconecto? ¿Cómo funciona la fábrica de bean autowire con dependencias en el caso? –

+2

Esto es realmente un mal patrón. Si así es como realmente usas MyBean, ¿por qué no tener simplemente constructor con AnotherBean como parámetro? Algo como: 'code' private @Autowired AnotherBean bean; public void doStuff() {MyBean obj = new MyBean (bean); } 'código'. Parece ser que con todas estas anotaciones la gente se confunde mucho y simplemente no usa el patrón básico que estaba en el SDK de Java desde el día 1. :( – Denis

-6

No sin algunas soluciones, como la primavera no sabe nada sobre este caso.

La verdadera pregunta es: ¿por qué está creando instancias de una clase en la que desea insertar las dependencias manualmente, en lugar de dejar que Spring lo controle? ¿Por qué no se inyecta la clase que usa MyClass en MyClass?

+12

Su respuesta es incorrecta, y su "verdadera pregunta" es un comentario, no una respuesta. –

13

También puede marcar su MiClase con anotación @Configurable:

@Configurable 
public class MyClass { 
    @Autowired private AnotherClass instance 
} 

A continuación, durante la creación inyectará automáticamente sus dependencias . También debe tener <context:spring-configured/> en su contexto de aplicación xml.

+2

Galz666, su método parece mucho más limpio para lo que quiero hacer. Sin embargo, no puedo hacer que funcione. No tengo ningún archivo xml y estoy usando completamente la configuración de Java. ¿Hay un equivalente a ''? – masstroy

+0

ver http://stackoverflow.com/a/4703781/404615 –

+0

Esta es una solución limpia, pero requiere un poco más de esfuerzo: debe utilizar el tejido en tiempo de carga como iimuhin muestra arriba o agregar el compilador AspectJ para proyectar. El tiempo de carga, como su nombre lo indica, causará un costo adicional en el tiempo de ejecución. – jsosnowski

0

Acabo de obtener la misma necesidad y en mi caso ya era la lógica dentro de la clase java no manejable de primavera que tenía acceso a ApplicationContext. Inspirado por scaffman. Resuelto por:

AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory(); 
factory.autowireBean(manuallyCreatedInstance); 
Cuestiones relacionadas