복붙노트

[SPRING] @Controller 클래스의 Spring @Value 주석은 속성 파일 내부의 값을 평가하지 않습니다.

SPRING

@Controller 클래스의 Spring @Value 주석은 속성 파일 내부의 값을 평가하지 않습니다.

나는 Spring을 처음 사용하고 @Controller annotation으로 주석을 붙인 컨트롤러 내부에 @Value ( "$ {loginpage.message}") 주석을 사용하여 문자열을 삽입하려고 시도하고 문자열의 값이 문자열 "$ {loginpage.message}"이며 내 등록 정보 파일 안에있는 것이 아닙니다.

아래는 내 컨트롤러에 주입하려는 문자열 '메시지'입니다.

@Controller
public class LoginController extends BaseController {
    @Value("${loginpage.message}")
    private String message;

    @RequestMapping("/")
    public String goToLoginPage(Model model) {
        model.addAttribute("message", message);

        return "/login";
    }
}

내 응용 프로그램 컨텍스트는 다음과 같습니다.

<context:property-placeholder location="classpath:properties/application.properties" />

<context:annotation-config />

<context:component-scan base-package="com.me.application" />

내 속성 파일에는 다음 행이 있습니다.

loginpage.message=this is a test message

@Value ( "$ {loginPage.message}")를 @Value ( "$ {notInPropertiesFile}")와 같은 속성 파일이 아닌 값으로 변경할 때마다 예외가 발생하기 때문에 Spring은 어느 시점에서 값을 선택해야합니다. .

해결법

  1. ==============================

    1.질문은 이미 물어 보입니다. Spring 3.0.5는 속성으로부터 @Value 주석을 평가하지 않습니다.

    질문은 이미 물어 보입니다. Spring 3.0.5는 속성으로부터 @Value 주석을 평가하지 않습니다.

    웹 애플리케이션 루트와 서블릿 애플리케이션 컨텍스트 간의 차이점은 Spring의 주요 혼란 원인 중 하나입니다 (Spring Framework의 applicationContext.xml과 spring-servlet.xml의 차이점 참조).

    @Value javadoc에서 :

    Spring 문서에서 :

  2. ==============================

    2.그렇다. 나는 Spring 3에서 같은 문제를 겪고있다. 그것은 Controller 내부에서 작동하지 않는 것 같다. 이 문제를 해결하기 위해 @Service를 가진 또 다른 bean을 생성하여 컨트롤러에 주입했습니다. 그것은 나를 위해 일했다. 이것이 내가 알아내는 데 하루 종일 보냈을 때 누군가에게 도움이되기를 바랍니다.

    그렇다. 나는 Spring 3에서 같은 문제를 겪고있다. 그것은 Controller 내부에서 작동하지 않는 것 같다. 이 문제를 해결하기 위해 @Service를 가진 또 다른 bean을 생성하여 컨트롤러에 주입했습니다. 그것은 나를 위해 일했다. 이것이 내가 알아내는 데 하루 종일 보냈을 때 누군가에게 도움이되기를 바랍니다.

  3. ==============================

    3.@Autowire Environment 다음에 environment.getProperty ( "name")를 사용할 수 있습니다. https://stackoverflow.com/a/15562319/632293을 참조하십시오.

    @Autowire Environment 다음에 environment.getProperty ( "name")를 사용할 수 있습니다. https://stackoverflow.com/a/15562319/632293을 참조하십시오.

  4. ==============================

    4.속성 파일에서 값을 추출 할 수 있으므로 @Value 주석을 사용하는 경우 PropertySourcePlaceHolder를 사용해야합니다. java config base를 사용하고 있다면 다음과 같이 bean을 생성해야합니다.

    속성 파일에서 값을 추출 할 수 있으므로 @Value 주석을 사용하는 경우 PropertySourcePlaceHolder를 사용해야합니다. java config base를 사용하고 있다면 다음과 같이 bean을 생성해야합니다.

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    

    또는 xml 기반을 사용하는 경우 그에 따라 빈을 선언하십시오.

  5. ==============================

    5.나는 봄 프로젝트에서 비슷한 이슈를 가지고 있었지만, 특히 BATCH 하나를 봄. 처음에는 내 구성을 아래와 같이 구축했습니다.

    나는 봄 프로젝트에서 비슷한 이슈를 가지고 있었지만, 특히 BATCH 하나를 봄. 처음에는 내 구성을 아래와 같이 구축했습니다.

    @Configuration
    public class BatchConfig   
    {
      @Bean
      public Job job(@Autowired Step stepMulti, @Autowired Step stepMultiDiff,  @Autowired Step stepMultiPolling
            ){
    
        Job job = jobBuilders.get("job")
                    .start(init0())
                        .on("POLLING").to(stepMultiPolling)
                    .from(init0()).on("*").to(stepMulti).next(stepMultiDiff).end()
                    .build();
        return job;
      }
    
      @Bean
      public Step init0(){
        return stepBuilders.get("init0")
                .tasklet(new MyDecider())
                .build();
      }
    
      ...
    }
    

    곧 MyDecider가 아래와 같이 나타납니다.

    public class MyDecider implements StepExecutionListener , Tasklet{ 
    
      @Autowired ThreadPoolTaskScheduler taskScheduler;
      @Value("${read.chunk.size}") private Integer pagesize;
    
    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
        return RepeatStatus.FINISHED;
    }
    
    @Override
    public ExitStatus afterStep(StepExecution exe) {
        String type = exe.getJobParameters().getString("mode");
    
        log.info("SPRING BATCH props:");
        log.info("    READ chunk size:  {}", pagesize);
    
    
        if (StringUtils.equals(type, "send")) {
            log.info("MODE batch SENDING...");
    
            if (taskScheduler !=null) taskScheduler.shutdown();
            else log.info("      Not able to stop scheduler (is null)");
    
            return new ExitStatus("SEND");
        } else  {
            log.info("MODE batch POLLING...");
            return new ExitStatus("POLLING");
        } 
    
    }
    

    그러나 이런 식으로 taskScheduler는 배선되지 않았으며 페이지 크기도 주입되지 않았습니다. 둘 다. Boris 대답 덕택에 일부 시도 후에 BatchConfig를 아래와 같이 완벽하게 변경했습니다.

    ...
    
    @Bean
    public Step init0(){
        return stepBuilders.get("init0")
                .tasklet(decider())
                .build();
    }
    
    @Bean
    public Tasklet decider() {
        return new MyDecider();
    }
    
    ...
    

    이유 : BatchConfig (decider () 중 하나)의 Bean 어노테이션에 더 가깝게 MyDecider를 구축하게되면, Spring은 MyDecider가 적절하게 주입되어야하고, application.property 값에 값이 있고, 사용 된 TaskScheduler로 유선되어야한다는 것을 이해하게 만든다. 또한 SpringScheduler 활성화가 필요하지만 jar 시작 옵션이 '보내기'인 경우에는 그것을 제거하고 싶습니다.)

    참고 : MyDecider 종료 상태가 SEND이고 POLLING이 아니기 때문에 옵션 mode = "send"를 사용하면 스프링 배치 작업이 stepMulti 방향으로 이동하지만 stepMultiPolling 방향으로 이동하지 않습니다. 하지만이 주제에 대한 설명 일 뿐이므로 자세한 내용은 건너 뜁니다.

    희망이 스프링 배치 사건은 누군가에게 도움이 될 수 있습니다!

  6. from https://stackoverflow.com/questions/11890544/spring-value-annotation-in-controller-class-not-evaluating-to-value-inside-pro by cc-by-sa and MIT license