programing

@Controller 클래스의 Spring @Value 주석이 속성 파일 내부의 값으로 평가되지 않음

newsource 2023. 7. 24. 22:31

@Controller 클래스의 Spring @Value 주석이 속성 파일 내부의 값으로 평가되지 않음

이고 Spring을 .@Value("${loginpage.message}")컨롤트주달주로 이 달린 @Controller 및 내 주 석 및 문 열 문 값 자 로 고 있 습 니 다 되 평 가 열 이 내 자 ▁as ▁the ▁string ▁annot ▁being 니 다 ▁the ▁is ▁evaluated ▁string ▁of 습 있 ▁value 주 ▁my"${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 3.0.5는 @Value Annotation from properties를 평가하지 않습니다.

웹 앱 루트와 서블릿 애플리케이션 컨텍스트의 차이는 봄에 가장 큰 혼란의 원인 중 하나입니다. Spring Framework에서 applicationContext.xml과 spring-servlet.xml의 차이를 참조하십시오.

@Valuejavadoc :

@Value 주석의 실제 처리는 BeanPostProcessor에 의해 수행됩니다.

Spring 문서에서:

BeanPostProcessor 인터페이스는 컨테이너별로 범위가 지정됩니다.이것은 컨테이너 계층 구조를 사용하는 경우에만 관련됩니다.한 컨테이너에 BeanPostProcessor를 정의하면 해당 컨테이너의 BeanPostProcessor에 대해서만 작업이 수행됩니다.한 용기에 정의된 콩은 두 용기가 동일한 계층 구조에 속하더라도 다른 용기의 BeanPostProcessor에 의해 사후 처리되지 않습니다.

네, 저는 봄 3과 같은 문제를 겪고 있습니다.컨트롤러 내부에서는 작동하지 않는 것 같습니다.이 문제를 해결하기 위해 @Service로 다른 빈을 만들고 컨트롤러에 주입했습니다.그것은 저에게 효과가 있었습니다.제가 하루 종일 고민한 만큼 이것이 누군가에게 도움이 되길 바랍니다.

속성 파일에서 값을 추출할 수 있으므로 @Value 주석을 사용하는 경우 PropertySourcePlaceHolder를 사용해야 합니다.Java 구성 기반을 사용하는 경우 다음과 같은 빈을 생성해야 합니다.

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

또는 xml 기반을 사용하는 경우 콩을 선언합니다.

넌 할 수 있다.@Autowire Environment그리고 나서.environment.getProperty("name")https://stackoverflow.com/a/15562319/632293 을 참조하십시오.

저는 봄 프로젝트에서 비슷한 문제가 있었지만, 특히 봄 배치 프로젝트에서 문제가 있었습니다.처음에는 아래와 같이 구성을 구축했습니다.

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

  ...
}

아래와 같이 곧 My Decider와 함께.

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

}

그러나 이러한 방식으로 스케줄러 작업이 연결되지 않았거나 페이지 크기가 주입되지 않았습니다. 둘 다 null입니다.Boris의 답변 덕분에, 저는 약간의 시도 끝에 BatchConfig를 아래와 같이 완벽하게 작동하도록 변경했습니다.

...

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

@Bean
public Tasklet decider() {
    return new MyDecider();
}

...

이유: BatchConfig(decider())의 Bean 주석에 MyDecider 구성을 더 가깝게 하면, application.property 값에 있는 값을 사용하여 MyDecider가 적절하게 주입되어야 하고 TaskScheduler가 사용된 상태로 연결되어야 한다는 것을 봄에 이해할 수 있습니다(SpringScheduler 활성화도 시도했기 때문에).하지만 병 시작 옵션이 '보내기'라면 끄고 싶었습니다.)

참고: 옵션 mode="send" 스프링 배치 작업은 단계 MultiPolling이 아니라 단계 MultiPolling으로 이동합니다. MyDecider 종료 상태가 Polling이 아니라 Send였기 때문입니다. 하지만 이것은 이 항목에 대한 설명일 뿐이므로 자세한 내용은 생략합니다.

이 봄 일괄 처리 사례가 누군가에게 도움이 되기를 바랍니다!

뻔한 질문을 해서 죄송합니다만, @Value 주석이 작동하지 않는다는 것을 어떻게 알 수 있습니까?Spring이 작동하는 방식의 문제점 중 하나는 Bean의 시공 후 Bean 전처리가 진행된다는 것입니다.

따라서 생성자에서 디버거를 사용하여 Bean을 검사하는 경우 설정된 필드를 볼 수 없습니다.감사()라는 메서드를 Bean에 추가하고 @PostConstruct로 주석을 달 수 있으며, 로그 문을 거기에 넣고 중단점을 지정하면 @Value 값을 가진 필드를 볼 수 있습니다.

그렇게 해도 @Value 필드가 표시되지 않으면 Bean을 스캔하지 않았을 수 있습니다.Bean을 구현하는 것으로 생각되는 클래스는 여전히 Java 클래스이며, 인스턴스화할 수 있으며 사전 처리되지 않은 경우 필드에 null이 할당됩니다.

Bean을 스캔하려면 클래스에 @Component 이상이 있어야 하며 클래스 패키지를 @ComponentScan에 추가해야 합니다.

@ComponentScan(basePackages = { "com.example.springboot", "org.bilbo.baggins" })

일반적으로 @ComponentScan을 찾을 수 있는 main() 메서드에 대한 원본이 없는 경우 동일한 패키지에 @Configuration 클래스를 추가하고 여기에 @ComponentScan을 추가할 수 있습니다.

이 예에서 @ComponentScan은 주석이 달린 행으로 잘못된 위치에 있습니다(@ImportResources를 대체해야 함).

package com.example.springboot;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

// @ComponentScan(basePackages = { "com.example.springboot", "org.bilbo.baggins" })
@Configuration
@ImportResource({"classpath*:applicationContext.xml"})
public class Configurer {
}

XML 파일 applicationContext.xml을 사용하는 방법을 보여주기 위해 이 작업을 수행했습니다.이것은 구성요소 스캔을 포함하고 Bean을 만듭니다.

(참고: 하나의 패키지만 스캔된다고 명시되어 있으며 구성 요소 스캔이 누적된 것 같습니다.)

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/sc
hema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/
beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema
/context/spring-context.xsd">

    <context:annotation-config />

    <context:component-scan base-package="org.bilbo.baggins" />
          <bean id="applicationProperties"
                      class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
                    <property name="location" value="classpath:application.properties" />
          </bean>
</beans>

XML 파일을 나열하고 XML 파일을 로드했음을 증명할 수 있도록 XML 파일에 빈을 작성하는 것이 유용합니다.방법을 사용하여 콩을 나열할 수 있습니다.String[] beanNames = ctx.getBeanDefinitionNames();

언급URL : https://stackoverflow.com/questions/11890544/spring-value-annotation-in-controller-class-not-evaluating-to-value-inside-pro