Odpowiedzi:
Krótko mówiąc, nie. W Spring nie można łączyć automatycznie ani ręcznie łączyć pól statycznych. Aby to zrobić, będziesz musiał napisać własną logikę.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThing
został zainicjowany jeśli obejrzano statycznie: NewClass.staticMethodWhichUsesSomething();
może rzucić NPE jeśli stosowany przed app inicjalizacji
Instance methods should not write to "static" fields (squid:S2696)
?
@Autowired
może być używany z ustawiaczami, więc możesz mieć setera modyfikującego pole statyczne.
Jeszcze jedna ostatnia sugestia ... NIE
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Zainicjuj swój autowired komponent w metodzie @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)
?
Możesz to osiągnąć za pomocą notacji XML i MethodInvokingFactoryBean
. Na przykład spójrz tutaj .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
Należy dążyć do stosowania wtrysku sprężyny, jeśli jest to możliwe, ponieważ jest to zalecane podejście, ale nie zawsze jest to możliwe, ponieważ jestem pewien, że możesz sobie wyobrazić, ponieważ nie wszystko można wyciągnąć z pojemnika sprężyny lub może masz do czynienia ze starszymi systemami.
Przy takim podejściu testowanie notatek może być również trudniejsze.
Chciałem dodać do odpowiedzi, że automatyczne podłączanie pola statycznego (lub stałego) zostanie zignorowane, ale także nie spowoduje żadnego błędu:
@Autowired
private static String staticField = "staticValue";
Możesz użyć ApplicationContextAware
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
następnie
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
Zrzeczenie się Nie jest to bynajmniej standard i może istnieć lepszy wiosenny sposób na zrobienie tego. Żadna z powyższych odpowiedzi nie rozwiązuje problemu okablowania publicznego pola statycznego.
Chciałem osiągnąć trzy rzeczy.
Mój obiekt wygląda tak
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
Już teraz odhaczyliśmy 1 i 2, w jaki sposób zapobiegamy wywołaniom ustawiacza, skoro nie możemy tego ukryć.
@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;
}
}
Ten aspekt zawinie wszystkie metody zaczynające się od final i zgłosi błąd, jeśli zostaną wywołane.
Nie sądzę, żeby to było szczególnie przydatne, ale jeśli jesteś ocd i lubisz oddzielać groszek i marchewkę, jest to jeden ze sposobów, aby zrobić to bezpiecznie.
Ważne Wiosna nie wywołuje twoich aspektów, gdy wywołuje funkcję. Ułatwiłem to, a szkoda, że opracowałem logikę, zanim to zrozumiałem.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);