1

I am having troubles with my Spring Boot initialization. I have this structure in a simple Spring Boot project.

com.project.name
|----App.java (Annoted with @SpringBootApplication and Autowire MyCustomService)
|----com.project.name.service
     |----MyCustomService.java (Annoted with @Service)

I tried setting scanBasePackages property in the SpringBootApplication Annotation but does not work. Anyway I have an @Bean annotated and I see that Spring Boot inject it correctly in the app because I can see the log when I run the application like this:

2019-03-09 15:23:47.917  INFO 21764 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'jobLauncherTaskExecutor'
...
2019-03-09 15:23:51.775  INFO 21764 --- [       Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'jobLauncherTaskExecutor'

A basic scheme of my AppClass.java

@SpringBootApplication(
        exclude = { DataSourceAutoConfiguration.class }
        //,scanBasePackages  = {"com.project.name.service"}
)

public class App{

    private static Logger logger = LoggerFactory.getLogger(App.class);

    @Autowired
    private static MyCustomService myCustomService;

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);

        ...

        myCustomService.anyMethod();//NullPointerException
    }
}

@Bean
public ThreadPoolTaskExecutor jobLauncherTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(10);
    executor.setMaxPoolSize(20);
    executor.setQueueCapacity(25);
    return executor;
}

I guess that I am missing something but I am reading some guides and does not find anything about this.

Genaut
  • 1,810
  • 2
  • 29
  • 60
  • 1
    Spring never autowires *static* fields. It creates Bean instances, and injects other beans instances into these beans. Read https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-command-line-runner for how to execute code at startup. – JB Nizet Mar 09 '19 at 14:35

2 Answers2

2

Spring cannot @Autowire static fields, use ApplicationContext to get the bean

@SpringBootApplication(
    exclude = { DataSourceAutoConfiguration.class }
    //,scanBasePackages  = {"com.project.name.service"}
)

public class App{

    private static Logger logger = LoggerFactory.getLogger(App.class);

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(App.class, args);

        MyCustomService myCustomService = (MyCustomService)context.getBean("myCustomService");
        ...

        myCustomService.anyMethod();
    }
}

Or you can use CommandLineRunner

 @SpringBootApplication(
    exclude = { DataSourceAutoConfiguration.class }
    //,scanBasePackages  = {"com.project.name.service"}
)

public class App implements CommandLineRunner {

    private static Logger logger = LoggerFactory.getLogger(App.class);

    @Autowired
    private MyCustomService myCustomService;

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
    public void run(String... args){
        myCustomService.anyMethod();
    }     
}
Genaut
  • 1,810
  • 2
  • 29
  • 60
Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98
  • I did a bad refactoring and I broke my application :) Thanks, I think I would have been stuck for a long time with this if it were not for your help. Thanks! Great CommandLineRunner Tip – Genaut Mar 09 '19 at 14:47
1

the problem has been solved before , please see link below

why can't we autowire static fields in spring

Minh Do
  • 35
  • 1
  • 7