Home > Net >  Thread at Springboot start, unable to read Property file
Thread at Springboot start, unable to read Property file

Time:09-17

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);
            }
        };
    }
}
  • Related