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.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
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'application
Instance 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
@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
@Component
public class TestClass {
private static AutowiredTypeComponent component;
@Autowired
private AutowiredTypeComponent autowiredComponent;
@PostConstruct
private void init() {
component = this.autowiredComponent;
}
public static void testMethod() {
component.callTestMethod();
}
}
Instance methods should not write to "static" fields (squid:S2696)
?
Vous pouvez y parvenir en utilisant la notation XML et le MethodInvokingFactoryBean
. Pour un exemple, regardez ici .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
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.
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:
@Autowired
private static String staticField = "staticValue";
Vous pouvez utiliser ApplicationContextAware
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
puis
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
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
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
Nous avons déjà coché 1 et 2 comment empêcher les appels au passeur, car nous ne pouvons pas le cacher.
@Component
@Aspect
public class FinalAutowiredHelper {
@Before("finalMethods()")
public void beforeFinal(JoinPoint joinPoint) {
throw new FinalAutowiredHelper().new ModifySudoFinalError("");
}
@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")
public void finalMethods() {}
public class ModifySudoFinalError extends Error {
private String msg;
public ModifySudoFinalError(String msg) {
this.msg = msg;
}
@Override
public String 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.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);