I am trying to execute a method in a separate thread, when the server starts. Please find my main class below:
@SpringBootApplication
@EnableSwagger2
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public TaskExecutor taskExecutor() {
return new SimpleAsyncTaskExecutor();
}
@Bean
public CommandLineRunner schedulingRunner(TaskExecutor executor) {
return new CommandLineRunner() {
public void run(String... args) throws Exception {
executor.execute(new CsvReader());
}
};
}
}
@Component
public class CsvReader implements Runnable{
@Value("${file-url}")
private String appUrl;
@Override
public void run() {
System.out.println("run after Object created: " appUrl); // this is coming as null. Not able to read it from application.properties
}
}
CodePudding user response:
You can use @PropertySource annotation.
Something like this
@SpringBootApplication
@PropertySource("application.properties")
@EnableSwagger2
public class Application {
// Your code
}
You can Autowire the value like this
@Component
public class CsvReader implements Runnable{
@Value("${property.name.from.application.properties.file}")
private String appUrl;
@Override
public void run() {
System.out.println("run after Object created: " appUrl); // this is coming as null. Not able to read it from application.properties
}
}
CodePudding user response:
Got the issue,
As I am executing CsvReader in a separate thread, container is not taking care of the bean initialisation, and thus dependency injections are not working.
Fixed the issue by
@Configuration
public class CsvReader {
@Value("${file-url}")
private String appUrl;
@PostConstruct
private void runAfterObjectCreated() {
Thread thread = new Thread() {
public void run() {
System.out.println("run after Object created: " appUrl);
}
};
thread.start();
}
}
With the above code, I am delegating the bean instantiation to the container.
@PostConstruct
, ensures execution, once the class is loaded, and because I have a Thread
class instantiated, by method is running in a new thread.
Option 2
@SpringBootApplication
@EnableSwagger2
public class Application {
@Autowired
private CsvReader csvReader;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public CommandLineRunner schedulingRunner(TaskExecutor executor) {
return new CommandLineRunner() {
public void run(String... args) throws Exception {
executor.execute(csvReader);
}
};
}
}