Méthode @Autowired et statique

J’ai un service @Autowired qui doit être utilisé à partir d’une méthode statique. Je sais que cela ne va pas, mais je ne peux pas changer le design actuel car cela nécessiterait beaucoup de travail, donc j’ai besoin d’un simple hack pour cela. Je ne peux pas changer randomMethod() pour être non statique et je dois utiliser ce bean auto-tiré. Des indices sur comment faire ça?

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

Vous pouvez le faire en suivant l’une des solutions suivantes:

Utiliser le constructeur @Autowired

Cette approche va construire le haricot nécessitant quelques haricots comme parameters constructeur. Dans le code constructeur, vous définissez le champ statique avec la valeur got comme paramètre pour l’exécution du constructeur. Échantillon:

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

Utiliser @PostConstruct pour remettre la valeur au champ statique

L’idée ici est de remettre un haricot à un champ statique après la configuration du haricot au spring.

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

Vous devez contourner ce problème via une approche d’accesseur de contexte d’application statique:

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

Vous pouvez ensuite accéder aux instances du bean de manière statique.

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

Qu’est-ce que vous pouvez faire est @Autowired une méthode de réglage et lui faire définir un nouveau champ statique.

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

Lorsque le bean est traité, Spring injecte une instance d’implémentation Foo dans le champ d’instance foo . Il injectera également la même instance de Foo dans la liste d’arguments setStaticFoo() , qui sera utilisée pour définir le champ statique.

Il s’agit d’une solution de contournement terrible et échouera si vous essayez d’utiliser randomMethod() avant que Spring n’ait traité une instance de Boo .

Il craint mais vous pouvez obtenir le bean en utilisant l’interface ApplicationContextAware . Quelque chose comme :

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

Utilisez AppContext. Assurez-vous de créer un bean dans votre fichier de contexte.

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