Tengo un @Autowired
servicio que debe usarse desde un método estático. Sé que esto está mal, pero no puedo cambiar el diseño actual, ya que requeriría mucho trabajo, por lo que necesito un truco simple para eso. No puedo cambiar randomMethod()
para ser no estático y necesito usar este bean autowired. ¿Alguna pista de cómo hacer eso?
@Service
public class Foo {
public int doStuff() {
return 1;
}
}
public class Boo {
@Autowired
Foo foo;
public static void randomMethod() {
foo.doStuff();
}
}
Respuestas:
Puede hacer esto siguiendo una de las soluciones:
Usando el constructor @Autowired
Este enfoque construirá el bean requiriendo algunos beans como parámetros de constructor. Dentro del código del constructor, estableces el campo estático con el valor obtenido como parámetro para la ejecución del constructor. Muestra:
Usando @PostConstruct para entregar el valor al campo estático
La idea aquí es entregar un bean a un campo estático después de que el bean esté configurado por Spring.
fuente
Debe solucionar esto a través del enfoque de acceso al contexto de la aplicación estática:
Luego, puede acceder a las instancias de bean de manera estática.
fuente
getBean
antes de que se inicialice el contexto (NPE) o después de que se destruya el contexto con sus beans. Este enfoque tiene la ventaja de que el acceso al contexto estático "feo" se incluye en un método / clase.Lo que puede hacer es
@Autowired
un método de establecimiento y hacer que establezca un nuevo campo estático.Cuando se procesa el bean, Spring inyectará una
Foo
instancia de implementación en el campo de la instanciafoo
. Luego, también inyectará la mismaFoo
instancia en lasetStaticFoo()
lista de argumentos, que se usará para establecer el campo estático.Esta es una solución terrible y fallará si intenta usar
randomMethod()
antes de que Spring haya procesado una instancia deBoo
.fuente
setStaticFoo()
es, sin elFoo
parámetro.Apesta, pero puedes obtener el bean usando la
ApplicationContextAware
interfaz. Algo como :fuente
Esto se basa en la respuesta de @ Pavel , para resolver la posibilidad de que el contexto Spring no se inicialice al acceder desde el método estático getBean:
La pieza importante aquí es el
initContext
método. Asegura que el contexto siempre se inicializará. Pero tenga en cuenta queinitContext
será un punto de discordia en su código ya que está sincronizado. Si su aplicación está muy paralelizada (por ejemplo, el backend de un sitio de alto tráfico), es posible que esta no sea una buena solución para usted.fuente
Utilice AppContext. Asegúrese de crear un bean en su archivo de contexto.
fuente