답변:
요컨대 스프링에서는 정적 필드를 자동 와이어 링하거나 수동으로 와이어 링 할 수 없습니다. 이를 위해서는 자신 만의 논리를 작성해야합니다.
@AutoWired
@Component("NewClass")
public class NewClass{
private static SomeThing someThing;
@Autowired
public void setSomeThing(SomeThing someThing){
NewClass.someThing = someThing;
}
}
someThing
정적으로 액세스하면 초기화되었다는 보장이 없습니다 : NewClass.staticMethodWhichUsesSomething();
앱 초기화 전에 사용하면 NPE가 발생할 수 있음
Instance methods should not write to "static" fields (squid:S2696)
?
@Autowired
setter와 함께 사용하면 정적 필드를 수정하는 setter를 가질 수 있습니다.
그냥 하나 개의 최종 제안 ... NOT DO
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
@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)
?
XML 표기법 및을 사용하여이 작업을 수행 할 수 있습니다 MethodInvokingFactoryBean
. 예를 들어 여기 를보십시오 .
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
StaticBean.staticBean = staticBean;
}
이것이 권장되는 접근 방식이므로 가능한 한 스프링 주입 을 사용하는 것을 목표로해야 하지만 스프링 컨테이너에서 모든 것을 가져올 수 없거나 레거시 시스템을 다룰 수는 없다고 생각할 수 있으므로 항상 가능하지는 않습니다.
이 방법으로는 노트 테스트가 더 어려울 수 있습니다.
ApplicationContextAware를 사용할 수 있습니다
@Component
public class AppContext implements ApplicationContextAware{
public static ApplicationContext applicationContext;
public AppBeans(){
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
그때
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
면책 조항 이것은 결코 표준이 아니며 이것을 수행하는 더 좋은 봄 방법이있을 수 있습니다. 위의 답변 중 어느 것도 공공 정적 필드 배선 문제를 해결하지 못합니다.
나는 세 가지를 성취하고 싶었다.
내 개체는 다음과 같습니다
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
BRANCH = branch;
}
public static String BRANCH() {
return BRANCH;
}
우리는 setter에 대한 호출을 숨길 수 없으므로 어떻게 1 & 2를 이미 확인했습니다.
@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;
}
}
이 측면은 final로 시작하는 모든 메소드를 랩핑하고 호출되면 오류를 발생시킵니다.
나는 이것이 특히 유용하다고 생각하지 않지만, 당신이 ocd이고 당신이 완두콩과 당근을 분리 된 상태로 유지하고 싶다면 이것을 안전하게하는 한 가지 방법입니다.
중요한 Spring은 함수를 호출 할 때 당신의 측면을 호출하지 않습니다. 이것을 쉽게하고 나쁘게 만들었습니다. 나는 그것을 이해하기 전에 논리를 해결했습니다.
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);