CONTEXT:
I process reports with @Scheduled
annotation and when invoke Component
from Service
property not getting initialized with @Value
annotation even it physically exists in .properties
and printed out in @PostConstruct
.
DESCRIPTION:
ReportProcessor
interface and InventoryReportProcessor
implementation:
@FunctionalInterface
interface ReportProcessor {
public void process(OutputStream outputStream);
}
@Component
public class InventoryReportProcessor implement ReportProcessor {
@Value("${reportGenerator.path}")
private String destinationFileToSave;
/*
@PostConstruct
public void init() {
System.out.println(destinationFileToSave);
}
*/
@Override
public Map<String, Long> process(ByteArrayOutputStream outputStream) throws IOException {
System.out.println(destinationFileToSave);
// Some data processing in here
return null;
}
}
I use it from
@Service
public class ReportService {
@Value("${mws.appVersion}")
private String appVersion;
/* Other initialization and public API methods*/
@Scheduled(cron = "*/10 * * * * *")
public void processReport() {
InventoryReportProcessor reportProcessor = new InventoryReportProcessor();
Map<String, Long> skus = reportProcessor.process(new ByteArrayOutputStream());
}
}
My confusion comes from the fact that @Value
in Service
works fine but in @Component
it returns null
unless call in @PostConstruct
. Also, if call @PostConstruct
the value is still remains null
in the rest of the class code.
I found similar Q&A and I did research in Srping docs but so far no single idea why it works this way and what can be a solution?
You need to Autowire the component to make your spring application aware of the component.
@Service
public class ReportService {
@Value("${mws.appVersion}")
private String appVersion;
/* Other initialization and public API methods*/
@Autowired
private ReportProcessor reportProcessor;
@Scheduled(cron = "*/10 * * * * *")
public void processReport() {
//InventoryReportProcessor reportProcessor = new InventoryReportProcessor();
Map<String, Long> skus = reportProcessor.process(new ByteArrayOutputStream());
}
}