SpringBootアプリケーションのMainメソッドで@AutowiredJPAリポジトリを使用できません
アプリケーションが起動する前に、H2データベースにダミーデータを追加するJPAリポジトリを自動配線しました。しかし、main()メソッドでは使用できないのに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));
};
}
}
回答
mainメソッドは静的とマークされています。つまり、そこで使用されるすべてのものも静的であるか、手動でインスタンス化する必要があります。
mainメソッドの静的本体でCarRepositoryを手動でインスタンス化するのではなく、Springを使用して、この行の「carRepository。// ....」の後に発生する起動フェーズのどこかでインスタンス化します。
そのため、carRepositoryはそれ自体では静的ではなく、手動でインスタンス化されていないため、この正確な場所で使用することはできません。
ただし、CommandRunnerでは、returnが呼び出された時点で、CarRepositoryのインスタンスはSpringによって既に作成されており、Springの起動がすでに終了しているため、フィールドに自動配線されており、簡単に使用できます。
Javaで許可されていない静的メソッドから直接非静的フィールドにアクセスしています
また、静的フィールドを作成することはできません @Autowired
だからあなたがこれをするなら
@Autowired
private static CarRepository carRepository;
エラーはスローされませんが、無視されます。
メインメソッドは静的としてマークされており、静的メソッドから非静的メンバーにアクセスすることはできません。
これを解決するには、carRepositoryを静的としてマークする必要があります。ただし、静的フィールドは自動配線できないため、無視され、オブジェクトを取得できません。
その時点でスプリントの起動はすでに終了しており、Beanがインスタンス化されているため、コマンドランナーで機能します。