Annotation @Value doesn't work properly in Spring Boot?

Dmytro Chasovskyi :

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?

Dhaval Simaria :

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=128999&siteId=1