L’annotazione Spring @Value nella class @Controller non sta valutando il valore nel file delle proprietà

Sono nuovo di Spring e sto provando ad inserire una stringa con un valore usando l’ @Value("${loginpage.message}") all’interno di un controller annotato con l’annotazione @Controller e il valore della mia stringa viene valutato come stringa "${loginpage.message}" e non ciò che è contenuto nel mio file delle proprietà.

Di seguito è il mio controller con la stringa ‘messaggio’ che voglio iniettare.

 @Controller public class LoginController extends BaseController { @Value("${loginpage.message}") private String message; @RequestMapping("/") public String goToLoginPage(Model model) { model.addAttribute("message", message); return "/login"; } } 

Il mio contesto applicativo si presenta così:

    

Il mio file di proprietà ha la linea:

 loginpage.message=this is a test message 

A un certo punto Spring deve ricevere il valore perché ogni volta che cambio @Value("${loginpage.message}") su un valore non nel file properties come @Value("${notInPropertiesFile}") , ottengo un’eccezione .

Sembra che la domanda sia già stata posta. Spring 3.0.5 non valuta l’annotazione @Value dalle proprietà

La differenza tra i contesti delle applicazioni Web root e dei servlet è una delle principali fonti di confusione in Spring, vedi Differenza tra applicationContext.xml e spring-servlet.xml in Spring Framework

Da @Value javadoc:

Si noti che l’elaborazione effettiva dell’annotazione @Value viene eseguita da un BeanPostProcessor

Dalla documentazione di spring:

Le interfacce BeanPostProcessor hanno un ambito per contenitore. Ciò è rilevante solo se si utilizzano le gerarchie del contenitore. Se si definisce un BeanPostProcessor in un contenitore, eseguirà il proprio lavoro sui bean solo in quel contenitore. I bean definiti in un contenitore non vengono elaborati da un BeanPostProcessor in un altro contenitore, anche se entrambi i contenitori fanno parte della stessa gerarchia.

Sì, sto avendo lo stesso problema con la spring 3. Non sembra funzionare all’interno dei controller. Per risolvere il problema ho creato un altro bean con @Service e l’ho inserito nel controller. Ha funzionato per me. Spero che questo possa essere d’aiuto a qualcuno dato che ho passato tutto il giorno a capirlo.

Puoi @Autowire Environment e quindi environment.getProperty("name") . Vedi https://stackoverflow.com/a/15562319/632293

È necessario utilizzare PropertySourcePlaceHolder se si utilizza l’annotazione @Value perché può estrarre il valore da un file delle proprietà. Se stai usando java config base devi creare un bean come questo

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

O se stai usando xml, allora dichiara il bean di conseguenza.

Ho avuto un problema simile nel mio progetto di spring, ma in particolare quello di spring BATCH. Ho costruito inizialmente la mia configurazione come di seguito

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

con MyDecider brevemente come sotto

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

Ma in questo modo né taskScheduler è stato cablato né è stato iniettato il pagesize; entrambi nulli. Grazie alla risposta di Boris, dopo qualche tentativo, ho cambiato BatchConfig come funziona perfettamente funzionante

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

Motivo: avendo la costruzione di MyDecider più vicina a un’annotazione Bean in BatchConfig (quella di decider () ), fai capire a spring che MyDecider deve essere iniettato correttamente, con valori trovati nei valori application.property e cablato con TaskScheduler usato (perché ho provato anche per avere l’triggerszione di SpringScheduler, ma volevo spegnerla se l’opzione di avvio di jar era ‘send’).

NOTA: con modalità opzione = “invia” il processo batch di spring prende il via verso stepMulti e non stepMultiPolling, perché lo stato di uscita di MyDecider era SEND e non POLLING; ma questa è solo una spiegazione di questo argomento, quindi salterò ulteriori dettagli.

Spero che questo caso di spring possa essere utile per qualcuno!