Antworten:
Kurz gesagt, nein. Sie können statische Felder in Spring nicht automatisch verdrahten oder manuell verdrahten. Sie müssen Ihre eigene Logik schreiben, um dies zu tun.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThingdie initialisiert wurde, wenn statisch zugegriffen wurde: NewClass.staticMethodWhichUsesSomething();Kann eine NPE auslösen, wenn sie vor der App-Initialisierung verwendet wird
Instance methods should not write to "static" fields (squid:S2696)?
@Autowired kann mit Setzern verwendet werden, sodass ein Setter ein statisches Feld ändern kann.
Nur ein letzter Vorschlag ... NICHT
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Initialisieren Sie Ihre automatisch verdrahtete Komponente in der @ PostConstruct-Methode
@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)?
Sie können dies mit der XML-Notation und der erreichen MethodInvokingFactoryBean. Ein Beispiel finden Sie hier .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
Sie sollten nach Möglichkeit die Federeinspritzung verwenden, da dies der empfohlene Ansatz ist , dies ist jedoch nicht immer möglich, da Sie sich sicher vorstellen können, dass nicht alles aus dem Federbehälter gezogen werden kann oder Sie sich möglicherweise mit Legacy-Systemen befassen.
Das Testen von Noten kann mit diesem Ansatz auch schwieriger sein.
Sie können ApplicationContextAware verwenden
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
dann
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
Wollte zu den Antworten hinzufügen, dass das statische Feld (oder die Konstante) der automatischen Verkabelung ignoriert wird, aber auch keinen Fehler erzeugt:
@Autowired
private static String staticField = "staticValue";
Haftungsausschluss Dies ist keineswegs Standard und es könnte durchaus einen besseren Frühlingsweg geben, dies zu tun. Keine der obigen Antworten befasst sich mit der Verdrahtung eines öffentlichen statischen Feldes.
Ich wollte drei Dinge erreichen.
Mein Objekt sieht so aus
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
Wir haben bereits 1 & 2 abgehakt, wie wir Anrufe an den Setter verhindern können, da wir sie nicht ausblenden können.
@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;
}
}
Dieser Aspekt umschließt alle Methoden, die mit final beginnen, und gibt einen Fehler aus, wenn sie aufgerufen werden.
Ich denke nicht, dass dies besonders nützlich ist, aber wenn Sie ok sind und Ihre Erbsen und Karotten getrennt halten möchten, ist dies eine Möglichkeit, dies sicher zu tun.
Wichtig Spring ruft Ihre Aspekte nicht auf, wenn es eine Funktion aufruft. Das wurde einfacher, schade, dass ich die Logik ausgearbeitet habe, bevor ich das herausgefunden habe.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);