En bref, non. Vous ne pouvez pas câbler automatiquement ou câbler manuellement les champs statiques dans Spring. Vous devrez écrire votre propre logique pour ce faire.
Lorsque vous trouvez un ancien code faisant cela, c'est un anti-pattern. Louchez, inclinez la tête et trouvez une meilleure façon de résoudre le problème. Vous serez heureux de l'avoir fait.
Joseph Lust
2
cette réponse est également utile sur Spring's@AutoWired
une idée de la façon dont je peux utiliser cette approche lors de l'initialisation d'un référentiel?
kiedysktos
3
L'inconvénient: il n'y a aucune garantie qui someThinga été initialisée en cas d'accès statique: NewClass.staticMethodWhichUsesSomething();peut lancer un NPE s'il est utilisé avant l'initialisation de l'application
Neeraj
Pouvez-vous éviter l'avertissement de Instance methods should not write to "static" fields (squid:S2696)?
user7294900
@ user7294900: désactivez cet avertissement pour ce seul cas très spécifique.
izogfif
@izogfif encore un problème si je choisis cette solution dans des cas et des classes
larges
67
@Autowired peut être utilisé avec des setters afin que vous puissiez avoir un setter modifiant un champ statique.
Hmmm .. mon sentiment sur la raison pour laquelle ce n'est pas recommandé est, car alors l'instance statique dans la classe est au-delà du contrôle de spring. Une fois injecté, le champ statique est la référence pour toutes les instances d'objets de la classe correspondante (environnante). Mais, ce comportement pourrait être exactement ce qui devrait se produire, donc pourrait être considéré comme un bogue ou une fonctionnalité ...
matthaeus
1
Oui @matthaeus, c'est exactement la fonctionnalité à laquelle je m'attendais lorsque j'ai besoin d'accéder à org.springframework.core.env.Environment:@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
user1767316
@JonLorusso et tout Parce que lorsque le chargeur de classe charge les valeurs statiques, le contexte Spring n'est pas encore nécessaire chargé. Ainsi, le chargeur de classe n'injectera pas correctement la classe statique dans le bean et échouera. Réponse fournie par Andrea T
Jeril Kuruvila
14
Initiez votre composant câblé automatiquement dans la méthode @PostConstruct
Vous devez viser à utiliser l'injection à ressort lorsque cela est possible car c'est l'approche recommandée mais ce n'est pas toujours possible, car je suis sûr que vous pouvez l'imaginer car tout ne peut pas être retiré du conteneur à ressort ou vous avez peut-être affaire à des systèmes hérités.
Les tests de notes peuvent également être plus difficiles avec cette approche.
Avertissement de non- Ce n'est en aucun cas une norme et il pourrait très bien y avoir une meilleure façon de procéder au printemps. Aucune des réponses ci-dessus n'aborde les problèmes de câblage d'un champ statique public.
Je voulais accomplir trois choses.
Utilisez le ressort pour "Autowire" (Im using @Value)
Nous avons déjà coché 1 et 2 comment empêcher les appels au passeur, car nous ne pouvons pas le cacher.
@Component@AspectpublicclassFinalAutowiredHelper{@Before("finalMethods()")publicvoid beforeFinal(JoinPoint joinPoint){thrownewFinalAutowiredHelper().newModifySudoFinalError("");}@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")publicvoid finalMethods(){}publicclassModifySudoFinalErrorextendsError{privateString msg;publicModifySudoFinalError(String msg){this.msg = msg;}@OverridepublicString getMessage(){return"Attempted modification of a final property: "+ msg;}}
Cet aspect encapsulera toutes les méthodes commençant par final et lèvera une erreur si elles sont appelées.
Je ne pense pas que cela soit particulièrement utile, mais si vous avez envie de séparer les pois et les carottes, c'est une façon de le faire en toute sécurité.
Important Spring n'appelle pas vos aspects lorsqu'il appelle une fonction. Rendu cela plus facile, c'est dommage, j'ai élaboré la logique avant de comprendre cela.
Bien que ce code puisse résoudre la question, inclure une explication sur comment et pourquoi cela résout le problème aiderait vraiment à améliorer la qualité de votre message et entraînerait probablement plus de votes à la hausse. N'oubliez pas que vous répondez à la question des lecteurs à l'avenir, pas seulement à la personne qui la pose maintenant. Veuillez modifier votre réponse pour ajouter des explications et donner une indication des limites et des hypothèses applicables.
double bip
Je pense que cette réponse n'a peut-être pas besoin d'explication du tout.
Réponses:
En bref, non. Vous ne pouvez pas câbler automatiquement ou câbler manuellement les champs statiques dans Spring. Vous devrez écrire votre propre logique pour ce faire.
la source
@AutoWired
la source
someThing
a été initialisée en cas d'accès statique:NewClass.staticMethodWhichUsesSomething();
peut lancer un NPE s'il est utilisé avant l'initialisation de l'applicationInstance methods should not write to "static" fields (squid:S2696)
?@Autowired
peut être utilisé avec des setters afin que vous puissiez avoir un setter modifiant un champ statique.Juste une dernière suggestion ... NE PAS
la source
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Initiez votre composant câblé automatiquement dans la méthode @PostConstruct
la source
Instance methods should not write to "static" fields (squid:S2696)
?Créez un bean que vous pouvez câbler automatiquement qui initialisera la variable statique comme un effet secondaire.
la source
Vous pouvez y parvenir en utilisant la notation XML et le
MethodInvokingFactoryBean
. Pour un exemple, regardez ici .Vous devez viser à utiliser l'injection à ressort lorsque cela est possible car c'est l'approche recommandée mais ce n'est pas toujours possible, car je suis sûr que vous pouvez l'imaginer car tout ne peut pas être retiré du conteneur à ressort ou vous avez peut-être affaire à des systèmes hérités.
Les tests de notes peuvent également être plus difficiles avec cette approche.
la source
Je voulais ajouter aux réponses que le champ statique de câblage automatique (ou constante) sera ignoré, mais ne créera également aucune erreur:
la source
Vous pouvez utiliser ApplicationContextAware
puis
la source
Avertissement de non- Ce n'est en aucun cas une norme et il pourrait très bien y avoir une meilleure façon de procéder au printemps. Aucune des réponses ci-dessus n'aborde les problèmes de câblage d'un champ statique public.
Je voulais accomplir trois choses.
Mon objet ressemble à ceci
Nous avons déjà coché 1 et 2 comment empêcher les appels au passeur, car nous ne pouvons pas le cacher.
Cet aspect encapsulera toutes les méthodes commençant par final et lèvera une erreur si elles sont appelées.
Je ne pense pas que cela soit particulièrement utile, mais si vous avez envie de séparer les pois et les carottes, c'est une façon de le faire en toute sécurité.
Important Spring n'appelle pas vos aspects lorsqu'il appelle une fonction. Rendu cela plus facile, c'est dommage, j'ai élaboré la logique avant de comprendre cela.
la source
la source