@Autowired e metodo statico

Ho un servizio @Autowired che deve essere utilizzato da un metodo statico. So che questo è sbagliato, ma non posso cambiare il progetto attuale in quanto richiederebbe molto lavoro, quindi ho bisogno di un semplice trucco per questo. Non posso cambiare randomMethod() per essere non-statico e ho bisogno di usare questo bean autowired. Qualche indizio su come farlo?

 @Service public class Foo { public int doStuff() { return 1; } } public class Boo { @Autowired Foo foo; public static void randomMethod() { foo.doStuff(); } } 

Puoi farlo seguendo una delle soluzioni:

Utilizzando il costruttore @Autowired

Questo approccio costruirà il bean che richiede alcuni bean come parametri del costruttore. All’interno del codice costruttore si imposta il campo statico con il valore ottenuto come parametro per l’esecuzione del costruttore. Campione:

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

Usando @PostConstruct per passare il valore al campo statico

L’idea qui è di consegnare un bean a un campo statico dopo che il bean è stato configurato dalla molla.

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

È necessario aggirare questo problema tramite l’approccio dell’accessor context context statico:

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

Quindi è ansible accedere alle istanze di bean in modo statico.

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

Quello che puoi fare è @Autowired un metodo setter e impostarlo su un nuovo campo statico.

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

Quando il bean viene elaborato, Spring inserisce una istanza di implementazione di Foo nel campo di istanza foo . setStaticFoo() poi la stessa istanza di Foo nella lista degli argomenti setStaticFoo() , che verrà usata per impostare il campo statico.

Questa è una soluzione terribile e fallirà se si tenta di usare randomMethod() prima che Spring abbia elaborato un’istanza di Boo .

Fa schifo ma puoi ottenere il bean usando l’interfaccia ApplicationContextAware . Qualcosa di simile a :

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

Usa AppContext. Assicurati di creare un bean nel tuo file di contesto.

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