Impossibile utilizzare @Autowired JPA Repository nel metodo principale dell'applicazione Spring Boot

Aug 24 2020

Ho autowired un repository JPA che aggiunge dati fittizi nel mio database H2 prima dell'avvio dell'applicazione. Ma c'è una ragione per cui non posso usarlo nel metodo main () ma sono in grado di usarlo nel metodo runner ()?

@SpringBootApplication
public class FullstackApplication {
    
    @Autowired
    private CarRepository carRepository;
    
    private static final Logger logger = LoggerFactory.getLogger(FullstackApplication.class); 

    public static void main(String[] args) {
        carRepository. // Here I get a compilation error: Cannot make a static reference to a non-static field
        SpringApplication.run(FullstackApplication.class, args);

    }
    
    @Bean
    CommandLineRunner runner(){
        return args -> {
            // Save demo data to database
            carRepository.save(new Car("Ford", "Mustang", "Red",
            "ADF-1121", 2017, 59000));
            carRepository.save(new Car("Nissan", "Leaf", "White",
            "SSJ-3002", 2014, 29000));
            carRepository.save(new Car("Toyota", "Prius", "Silver",
            "KKO-0212", 2018, 39000));
        };
    }
}

Risposte

2 DanyloGurianov Aug 24 2020 at 17:49

Il metodo principale è contrassegnato come statico, il che significa che anche tutto ciò che viene utilizzato dovrebbe essere statico o essere istanziato manualmente.

Non si istanzia CarRepository manualmente nel corpo statico del metodo principale, ci si affida a Spring per istanziarlo da qualche parte durante la fase di avvio, che avverrà dopo "carRepository. // ...." questa riga.

Questo è il motivo per cui non è possibile utilizzare carRepository in questo punto esatto, perché non è statico di per sé e non è stato istanziato manualmente.

In CommandRunner, tuttavia, al momento viene chiamato return, l'istanza di CarRepository è già creata da Spring e autowired al campo, perché l'avvio di Spring è già terminato e può essere facilmente utilizzato.

2 Shubh Aug 24 2020 at 17:46

Stai accedendo a un campo non statico direttamente dal metodo statico che non è consentito in java

Inoltre non puoi creare un campo statico @Autowired

quindi se lo fai

@Autowired
  private static CarRepository carRepository;

non genererà alcun errore ma verrà ignorato.

1 AnkushSharma Aug 24 2020 at 18:44

Bene, il metodo principale è contrassegnato come statico e non è possibile accedere a membri non statici da un metodo statico.

Per risolverlo devi contrassegnare il file carRepository come statico. Ma poiché il campo statico non può essere cablato automaticamente, lo ignorerà e non otterrai l'oggetto.

Funzionerà in command runner perché in quel momento l'avvio dello sprint è già terminato e i bean sono stati istanziati.