Risposte:
In breve, no. In primavera non è possibile eseguire il collegamento automatico o collegare manualmente i campi statici. Dovrai scrivere la tua logica per farlo.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThingè stata inizializzata se si accede staticamente: NewClass.staticMethodWhichUsesSomething();potrebbe generare un NPE se utilizzato prima dell'inizializzazione dell'app
Instance methods should not write to "static" fields (squid:S2696)?
@Autowired può essere utilizzato con setter in modo da poter avere un setter che modifica un campo statico.
Solo un ultimo suggerimento ... NON
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Iniziare il componente autowired nel metodo @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)?
È possibile ottenere ciò utilizzando la notazione XML e il MethodInvokingFactoryBean. Per un esempio guarda qui .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
Dovresti mirare a usare l' iniezione a molla laddove possibile in quanto questo è l'approccio raccomandato ma questo non è sempre possibile in quanto sono sicuro che puoi immaginare come non tutto può essere estratto dal contenitore a molla o forse hai a che fare con sistemi legacy.
Nota che testare può anche essere più difficile con questo approccio.
Volevo aggiungere alle risposte che il campo statico (o costante) del cablaggio automatico verrà ignorato, ma non creerà alcun errore:
@Autowired
private static String staticField = "staticValue";
È possibile utilizzare ApplicationContextAware
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
poi
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
Disclaimer Questo non è affatto standard e potrebbe esserci un modo migliore per farlo. Nessuna delle risposte di cui sopra risolve i problemi legati al cablaggio di un campo statico pubblico.
Volevo realizzare tre cose.
Il mio oggetto si presenta così
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
Abbiamo spuntato 1 e 2 già ora come possiamo impedire le chiamate al setter, dal momento che non possiamo nasconderlo.
@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;
}
}
Questo aspetto includerà tutti i metodi che iniziano con final e genererà un errore se vengono chiamati.
Non penso che questo sia particolarmente utile, ma se sei ocd e ti piace tenere separati piselli e carote, questo è un modo per farlo in sicurezza.
Importante Spring non chiama i tuoi aspetti quando chiama una funzione. Reso più facile, peccato che abbia elaborato la logica prima di capirlo.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);