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();
}