J'ai un @Autowired
service qui doit être utilisé à partir d'une méthode statique. Je sais que c'est faux mais je ne peux pas changer la conception actuelle car cela demanderait beaucoup de travail, donc j'ai besoin d'un simple hack pour cela. Je ne peux pas changer randomMethod()
pour être non statique et j'ai besoin d'utiliser ce bean câblé automatiquement. Des indices comment faire ça?
@Service
public class Foo {
public int doStuff() {
return 1;
}
}
public class Boo {
@Autowired
Foo foo;
public static void randomMethod() {
foo.doStuff();
}
}
Réponses:
Vous pouvez le faire en suivant l'une des solutions:
Utilisation du constructeur @Autowired
Cette approche construira le bean nécessitant des beans comme paramètres de constructeur. Dans le code du constructeur, vous définissez le champ statique avec la valeur obtenue comme paramètre pour l'exécution du constructeur. Échantillon:
Utiliser @PostConstruct pour transmettre la valeur au champ statique
L'idée ici est de remettre un bean à un champ statique après que le bean est configuré par le ressort.
la source
Vous devez contourner cela via une approche d'accesseur de contexte d'application statique:
Ensuite, vous pouvez accéder aux instances de bean de manière statique.
la source
getBean
avant l'initialisation du contexte (NPE) ou après la destruction du contexte avec ses beans. Cette approche a pour avantage que l'accès au contexte statique "laid" est inclus dans une méthode / classe.Ce que vous pouvez faire est
@Autowired
une méthode setter et lui faire définir un nouveau champ statique.Lorsque le bean sera traité, Spring injectera une
Foo
instance d'implémentation dans le champ d'instancefoo
. Il injectera ensuite également la mêmeFoo
instance dans lasetStaticFoo()
liste d'arguments, 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 deBoo
.la source
setStaticFoo()
ce, sans leFoo
paramètre.Ça craint mais vous pouvez obtenir le bean en utilisant l'
ApplicationContextAware
interface. Quelque chose comme :la source
Cela s'appuie sur la réponse de @ Pavel , pour résoudre la possibilité que le contexte Spring ne soit pas initialisé lors de l'accès à partir de la méthode getBean statique:
L'élément important ici est la
initContext
méthode. Cela garantit que le contexte sera toujours initialisé. Mais, notez que ceinitContext
sera un point de discorde dans votre code car il est synchronisé. Si votre application est fortement parallélisée (par exemple: le backend d'un site à fort trafic), cela peut ne pas être une bonne solution pour vous.la source
Utilisez AppContext. Assurez-vous de créer un bean dans votre fichier de contexte.
la source