Programing

정적 필드와 함께 @Autowired를 사용할 수 있습니까?

lottogame 2020. 7. 8. 08:14
반응형

정적 필드와 함께 @Autowired를 사용할 수 있습니까?


@Autowired정적 필드와 함께 사용 하는 방법이 있습니까? 그렇지 않은 경우 다른 방법이 있습니까?


요컨대 스프링에서는 정적 필드를 자동 와이어 링하거나 수동으로 와이어 링 할 수 없습니다. 이를 위해서는 자신 만의 논리를 작성해야합니다.


@Component("NewClass")
public class NewClass{
    private static SomeThing someThing;

    @Autowired
    public void setSomeThing(SomeThing someThing){
        NewClass.someThing = someThing;
    }
}

@Autowired setter와 함께 사용할 수 있으므로 setter가 정적 필드를 수정하도록 할 수 있습니다.

그냥 하나 개의 최종 제안 ... NOT DO


@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();
   }
}

정적 변수를 부작용으로 초기화하는 autowire가 가능한 bean을 작성하십시오.


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);

면책 조항 이것은 결코 표준이 아니며 이것을 수행하는 더 좋은 봄 방법이있을 수 있습니다. 위의 답변 중 어느 것도 공공 정적 필드 배선 문제를 해결하지 못합니다.

나는 세 가지를 성취하고 싶었다.

  1. 스프링을 사용하여 "자동 와이어 링"(@Value를 사용하고 있음)
  2. 공개 정적 값 노출
  3. 수정 방지

내 개체는 다음과 같습니다

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;
    }
}

This aspect will wrap all methods beginning with final and throw an error if they are called.

I dont think this is particularly useful, but if you are ocd and like to keep you peas and carrots separated this is one way to do it safely.

Important Spring does not call your aspects when it calls a function. Made this easier, to bad I worked out the logic before figuring that out.


private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);

참고URL : https://stackoverflow.com/questions/1018797/can-you-use-autowired-with-static-fields

반응형