java spring static autowired

java - @ Método autoaumentado y estático



spring static (5)

Tengo el servicio @Autowired 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 que no sea 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(); } }


Apesta pero puedes obtener el bean usando la interfaz ApplicationContextAware . Algo como :

public class Boo implements ApplicationContextAware { private static ApplicationContext appContext; @Autowired Foo foo; public static void randomMethod() { Foo fooInstance = appContext.getBean(Foo.class); fooInstance.doStuff(); } @Override public void setApplicationContext(ApplicationContext appContext) { Boo.appContext = appContext; } }


Lo que puede hacer es @Autowired un método setter y establecer un nuevo campo estático.

public class Boo { @Autowired Foo foo; static Foo staticFoo; @Autowired public void setStaticFoo(Foo foo) { Boo.staticFoo = foo; } public static void randomMethod() { staticFoo.doStuff(); } }

Cuando se procesa el bean, Spring inyectará una instancia de implementación de Foo en el campo de instancia foo . También inyectará la misma instancia de Foo en la lista de argumentos setStaticFoo() , que se usará para establecer el campo estático.

Esta es una solución terrible y fallará si intenta utilizar randomMethod() antes de que Spring haya procesado una instancia de Boo .


Puede hacer esto siguiendo una de las soluciones:

Usando el constructor @Autowired

Este enfoque construirá el bean que requiere algunos beans como parámetros de constructor. Dentro del código del constructor, establece el campo estático con el valor obtenido como parámetro para la ejecución del constructor. Muestra:

@Component public class Boo { private static Foo foo; @Autowired public Boo(Foo foo) { Boo.foo = foo; } public static void randomMethod() { foo.doStuff(); } }

Usando @PostConstruct para entregar el valor al campo estático

La idea aquí es entregar un frijol a un campo estático después de que Bean esté configurado para la primavera.

@Component public class Boo { private static Foo foo; @Autowired private Foo tFoo; @PostConstruct public void init() { Boo.foo = tFoo; } public static void randomMethod() { foo.doStuff(); } }


Tienes que solucionar esto a través del enfoque de acceso al contexto de la aplicación estática:

@Component public class StaticContextAccessor { private static StaticContextAccessor instance; @Autowired private ApplicationContext applicationContext; @PostConstruct public void registerInstance() { instance = this; } public static <T> T getBean(Class<T> clazz) { return instance.applicationContext.getBean(clazz); } }

Luego puede acceder a las instancias de bean de manera estática.

public class Boo { public static void randomMethod() { StaticContextAccessor.getBean(Foo.class).doStuff(); } }


Use AppContext. Asegúrese de crear un bean en su archivo de contexto.

private final static Foo foo = AppContext.getApplicationContext().getBean(Foo.class); public static void randomMethod() { foo.doStuff(); }