58

私はSpringが初めて@Value("${loginpage.message}")で、注釈で注釈が付けられたコントローラー内の注釈を使用して値を文字列に挿入しようとしていますが、文字列の値はプロパティファイル内のものではなく@Controller文字列として評価されています。"${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}")のようにプロパティ ファイルにない値に変更すると例外が発生するため、Spring はある時点で値を取得している必要が@Value("${notInPropertiesFile}")あります。

4

6 に答える 6

68

Spring 3.0.5 は@Valueアノテーションをプロパティから評価しない

Web アプリ ルートとサーブレット アプリケーション コンテキストの違いは、Spring での混乱の主な原因の 1 つです 。Spring Framework での applicationContext.xml と spring-servlet.xml の違いを参照してください。

@Valuejavadocから:

@Value アノテーションの実際の処理は BeanPostProcessor によって実行されることに注意してください。

春のドキュメントから:

BeanPostProcessor インターフェースは、コンテナーごとにスコープされます。これは、コンテナ階層を使用している場合にのみ関係します。1 つのコンテナーで BeanPostProcessor を定義すると、そのコンテナー内の Bean に対してのみ作業が行われます。1 つのコンテナーで定義された Bean は、両方のコンテナーが同じ階層の一部であっても、別のコンテナーの BeanPostProcessor によって後処理されません。

于 2012-08-09T20:24:43.580 に答える
7

はい、Spring 3 でも同じ問題が発生しています。コントローラー内では機能しないようです。この問題を解決するために、@Service を使用して別の Bean を作成し、それをコントローラーに注入しました。それは私にとってはうまくいきました。私はそれを理解するために一日中費やしたので、これが誰かに役立つことを願っています.

于 2013-06-04T09:58:53.100 に答える
3

@Value アノテーションを使用している場合は、プロパティ ファイルから値を抽出できるため、PropertySourcePlaceHolder を使用する必要があります。Java config base を使用している場合は、このような Bean を作成する必要があります

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

または、xml ベースを使用している場合は、それに応じて Bean を宣言します。

于 2016-10-16T14:22:40.597 に答える
0

春のプロジェクトでも同様の問題がありましたが、特に春のBATCH 1です。以下のように最初に設定を作成しました

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

...

理由: MyDecider の構築を BatchConfig の Bean アノテーション (決定者()のアノテーション) に近づけることで、Application.property 値で見つかった値を使用して MyDecider を適切に注入し、TaskScheduler を使用して配線する必要があることを Spring に理解させます (私が試したため)また、SpringScheduler をアクティブ化する必要がありますが、jar 開始オプションが「send」の場合はオフにしたかったのです)。

注: オプション mode="send" を使用すると、Spring バッチ ジョブは stepMultiPolling ではなく stepMulti に進みます。これは、MyDecider の終了ステータスが POLLING ではなく SEND であったためです。しかし、それはこのトピックからの説明にすぎないため、詳細は省略します。

この春のバッチケースが誰かの役に立ちますように!

于 2017-04-24T10:23:43.377 に答える