英文:
Not able to read values using @Value in application.yaml in Springboot
问题
我正在使用Spring Boot - 2.3.3.RELEASE。在application.yaml中有一些值,我正在尝试使用@Value注解将它们注入到类中。但出于某些原因,它们没有被加载。结果应该是在SendPhoneByPhoneNumbers.java中,我们应该能够从application.yaml中读取notificationServiceURL。
注意- 我正在使用工厂和策略模式。该项目将被其他项目用作库,以导入并使用服务层公开的方法。
这是文件夹结构:https://i.stack.imgur.com/jpbNj.jpg
我正在尝试通过以调试模式运行Demo.java来查看实际值的外观。
application.yaml
notificationService:
url: "https://someURL.com"
Demo.java
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@SpringBootApplication
public class Demo {
public static void main(String[] args) {
SpringApplication.run(Demo.class, args);
String title="Title";
String message="message";
List<String> phoneNumbers = new ArrayList<>();
phoneNumbers.add("333-222-1111");
PhoneService phoneService = new PhoneService();
phoneService.sendNotificationByPhoneNumbers(title, message, phoneNumbers);
}
}
PhoneService.java
@Service
public class PhoneService {
PhoneServiceImpl notificationServiceImpl = new PhoneServiceImpl();
public void sendNotificationByPhoneNumbers(String title, String message, List<String> phoneNumbers) {
notificationServiceImpl.sendNotificationByPhoneNumbers(title, message, phoneNumbers);
}
}
PhoneServiceImpl.java
@Slf4j
@Component
public class PhoneServiceImpl {
@Value("${notificationService.url}")
String url;
public void sendNotificationByPhoneNumbers(String title, String message, List<String> phoneNumbers) {
PhoneContext phoneContext = new PhoneContext(new SendPhoneByPhoneNumbers(url));
phoneContext.notify(title, message, phoneNumbers);
}
}
PhoneContext.java
public class PhoneContext {
private PhoneStrategy phoneStrategy;
public PhoneContext(PhoneStrategy phoneStrategy){
this.phoneStrategy = phoneStrategy;
}
public void notify(String title, String message, List<String> employees){
phoneStrategy.sendNotification(title, message, employees);
}
}
PhoneStrategy.java
public interface PhoneStrategy {
public void sendNotification(String title, String message, List
}
SendPhoneByPhoneNumbers.java
@Slf4j
public class SendPhoneByPhoneNumbers implements PhoneStrategy {
RestTemplate restTemplate;
String notificationServiceURL;
BuildHttpRequest buildHttpRequest;
public SendPhoneByPhoneNumbers(String notificationServiceURL) {
this.notificationServiceURL = notificationServiceURL;
this.restTemplate = new RestTemplate();
this.buildHttpRequest = new BuildHttpRequest();
}
@Async
public void sendNotification(String title, String message, List<String> phoneNumbers) {
SmsMessage smsMessage= new SmsMessage(title, message, phoneNumbers, Collections.emptyList(), Collections.emptyList());
try {
HttpHeaders headers = new HttpHeaders();
headers.set("idToken", buildHttpRequest.getNewToken());
HttpEntity<SmsMessage> newRequest = new HttpEntity<>(smsMessage, headers);
restTemplate.postForObject(notificationServiceURL + "/someUrl", newRequest, String.class);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
此外,如果您对修改代码/结构以使其更好的方式有任何建议,请务必提出。
提前致谢。
英文:
I'm using Spring boot - 2.3.3.RELEASE. There are some values in application.yaml which I'm trying to inject in the classes using @Value annotation. But for some reason, they are not loading up. The result should be that, in SendPhoneByPhoneNumbers.java, we should be able to read notificationServiceURL from application.yaml.
Note- I'm using Factory and Strategy pattern. This project is going to be used as a Library for other projects to import and use the methods exposed by Service layer.
Here is the folder structure: https://i.stack.imgur.com/jpbNj.jpg
I'm trying to test by running Demo.java in Debug mode to see how the actual values looks like.
application.yaml
notificationService:
url: "https://someURL.com"
Demo.java
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@SpringBootApplication
public class Demo {
public static void main(String[] args) {
SpringApplication.run(Demo.class, args);
String title="Title";
String message="message";
List<String> phoneNumbers = new ArrayList<>();
phoneNumbers.add("333-222-1111");
PhoneService phoneService = new PhoneService();
phoneService.sendNotificationByPhoneNumbers(title, message, phoneNumbers);
}
}
PhoneService.java
@Service
public class PhoneService {
PhoneServiceImpl notificationServiceImpl = new PhoneServiceImpl();
public void sendNotificationByPhoneNumbers(String title, String message, List<String> phoneNumbers) {
notificationServiceImpl.sendNotificationByPhoneNumbers(title, message, phoneNumbers);
}
}
PhoneServiceImpl.java
@Slf4j
@Component
public class PhoneServiceImpl {
@Value("${notificationService.url}")
String url;
public void sendNotificationByPhoneNumbers(String title, String message, List<String> phoneNumbers) {
PhoneContext phoneContext = new PhoneContext(new SendPhoneByPhoneNumbers(url));
phoneContext.notify(title, message, phoneNumbers);
}
}
PhoneContext.java
public class PhoneContext {
private PhoneStrategy phoneStrategy;
public PhoneContext(PhoneStrategy phoneStrategy){
this.phoneStrategy = phoneStrategy;
}
public void notify(String title, String message, List<String> employees){
phoneStrategy.sendNotification(title, message, employees);
}
}
PhoneStrategy.java
public interface PhoneStrategy {
public void sendNotification(String title, String message, List<String> listOfEmployeeIdGroupNamePhoneNumbers);
}
SendPhoneByPhoneNumbers.java
@Slf4j
public class SendPhoneByPhoneNumbers implements PhoneStrategy {
RestTemplate restTemplate;
String notificationServiceURL;
BuildHttpRequest buildHttpRequest;
public SendPhoneByPhoneNumbers(String notificationServiceURL) {
this.notificationServiceURL = notificationServiceURL;
this.restTemplate = new RestTemplate();
this.buildHttpRequest = new BuildHttpRequest();
}
@Async
public void sendNotification(String title, String message, List<String> phoneNumbers) {
SmsMessage smsMessage= new SmsMessage(title, message, phoneNumbers, Collections.emptyList(), Collections.emptyList());
try {
HttpHeaders headers = new HttpHeaders();
headers.set("idToken", buildHttpRequest.getNewToken());
HttpEntity<SmsMessage> newRequest = new HttpEntity<>(smsMessage, headers);
restTemplate.postForObject(notificationServiceURL + "/someUrl", newRequest, String.class);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
Also, if you guys have any suggestions on modifying the code/structure in an way to make it better, please do suggest.
Thanks in advance.
答案1
得分: 1
PhoneService phoneService = new PhoneService();
由于您使用的 PhoneService
不是 Spring 容器中的托管bean,所以值没有被注入。
代码改进和修复
String title = "Title";
String message = "message";
List<String> phoneNumbers = new ArrayList<>();
phoneNumbers.add("333-222-1111");
// PhoneService phoneService = new PhoneService();
phoneService.sendNotificationByPhoneNumbers(title, message, phoneNumbers);
将此代码移动到实现了 CommandLineRunner
或 ApplicationRunner
接口的类中,并覆盖相应的 run()
方法。在该类中,您可以使用 @Autowired
注入 PhoneService
,而不是手动实例化它。另外请注意,您需要在这个类上标记 @Component
注解。
其他建议的小改动:
- 您可以将
SendPhoneByPhoneNumbers
类设置为单例。如果有多个实现,请使用@Qualifier
。 RestTemplate
和BuildHttpRequest
都可以使用@Bean
注解创建。- 由于您正在使用 lombok,考虑使用
@RequiredArgsConstructor
也是一个选择。
英文:
PhoneService phoneService = new PhoneService();
Since PhoneService
that you are using is not a managed bean by spring container, the values are not being injected.
Code Improvement and FIX
String title="Title";
String message="message";
List<String> phoneNumbers = new ArrayList<>();
phoneNumbers.add("333-222-1111");
// PhoneService phoneService = new PhoneService();
phoneService.sendNotificationByPhoneNumbers(title, message, phoneNumbers);
Move this code to a class implementing CommanLineRunner
or ApplicationRunner
and override corresponding run()
. In this class, you could @Autowire
PhoneService
rather than manually instantiating it. Also note that you have to mark this class with @Component
Other minor suggested changes:
- You can make
SendPhoneByPhoneNumbers
class a singleton. If there are multiple implementions, use@Qualifier
- Both
RestTemplate
andBuildHttpRequest
could be created using@Bean
annotation. - Since you are using lombok, using
@RequiredArgsConstructor
could also be considered.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论