2016-10-26 3 views
1

Я прочитал почти все, что могу найти, и по какой-то причине я не могу полностью заткнуть мозг вокруг того, как сделать эту работу. После борьбы в существующем проекте в течение 2 дней я загружал Начало работы Содержания для отдыха от Spring.ioДоступ к Spring Boot application.properties с использованием аннотации @Value

https://spring.io/guides/gs/rest-service/

Я создал папку ресурсов в основной папке и добавлен файл с именем application.properties следующим :

my.setting = HELLOTHERE 

затем я изменил поздравительный класс следующим образом:

package hello; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.boot.autoconfigure.domain.EntityScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.stereotype.Component; 

@Component 
public class Greeting { 

    private long id; 
    private String content; 
    private String dooDad; 
    public Greeting(long id, String content) { 
     this.id = id; 
     this.content = content; 
    } 

    public Greeting() { 
     // TODO Auto-generated constructor stub 
    } 

    public long getId() { 
     return id; 
    } 

    public String getContent() { 
     return content; 
    } 

    public String getDooDad() { 
     return dooDad; 
    } 
    @Autowired 
    public void setDooDad(@Value("${my.setting}")String dooDad) { 
     this.dooDad = dooDad; 
    } 
} 

Я изменил Appl класс ication иметь @Configuration аннотацию следующим образом:

package hello; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.annotation.Configuration; 

@SpringBootApplication 
@Configuration 
public class Application { 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

Я не изменить класс GreetingController, но будет включать его для полноты:

package hello; 

import java.util.concurrent.atomic.AtomicLong; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.RestController; 

@RestController 
public class GreetingController { 

    private static final String template = "Hello, %s!"; 
    private final AtomicLong counter = new AtomicLong(); 

    @RequestMapping("/greeting") 
    public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { 
     return new Greeting(counter.incrementAndGet(), 
          String.format(template, name)); 
    } 
} 

Когда я запустить приложение и посмотреть на выходе Я ожидал увидеть значение для dooDad, вместо этого он всегда равен нулю.

{"id":1,"content":"Hello, mike!","dooDad":null} 

Любая помощь в получении этой информации будет оценена по достоинству. Я обнаружил, что если бы я поместил аннотацию @Value на переменную в классе Application, она заполнила бы эту переменную с правильным значением, только если она не в классе приветствия?

ответ

3

Вы обходя инъекции зависимостей путем создания объекта Greeting себя:

return new Greeting(counter.incrementAndGet(), 
          String.format(template, name)); 

Таким образом @Component и @Value аннотаций в пределах Greeting объекта ничего не делает (для этого конкретного экземпляра).

Я предложил бы делать следующее:

  1. Сделать поздравительный объект стандартного POJO
  2. Включать в конструкторе
  3. Используйте @Value("${my.setting}") String dooDad как поле String dooDad в вашем Greeting Controller
  4. Pass dooDad в ваш новый приветственный объект:

    return new Gr eeting (counter.incrementAndGet(), String.format (шаблон, имя), dooDad);

Update: Добавлена ​​example project для иллюстрации различных вариантов достижения установки, описанной в ОП.

+0

Это имеет смысл в данном конкретном случае, но я также хотел бы иметь возможность установить значение по умолчанию для конечной точки, которая будет принимать JSON в качестве входных данных.JSON не обязательно будет содержать весь объект в этом примере, он мог бы содержать только «{« id »: 0,« content »:« foo »}' Я хотел бы, чтобы Джексон просто установил значение dooDad, используя '@Value '. Если я понимаю, что вы говорите, хотя мне придется проверить значение dooDad в конечной точке и установить его в '@ Value', если оно равно null? Разве нет другого пути? –

+0

@MichaelHatch Абсолютно. В этом случае мы изменим RequestMethod на POST и установим значение по умолчанию в RequestParam (как вы это сделали с параметром name). Это самый чистый подход. Если для dooDad не будет представлено значение, оно будет использовать значение по умолчанию. Теперь, если вы настаиваете на том, чтобы установить это значение по умолчанию из файла свойств, оно становится немного более подробным, но это можно сделать. Подробнее см. В моем примере репо: https://github.com/kanderson450/stackoverflow-q40271433 Мастер-ветвь - это простой подход, но проверьте ветвь функции для подхода к файлу свойств. –

Смежные вопросы