SpringBootアプリケーションのMainメソッドで@AutowiredJPAリポジトリを使用できません

Aug 24 2020

アプリケーションが起動する前に、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));
        };
    }
}

回答

2 DanyloGurianov Aug 24 2020 at 17:49

mainメソッドは静的とマークされています。つまり、そこで使用されるすべてのものも静的であるか、手動でインスタンス化する必要があります。

mainメソッドの静的本体でCarRepositoryを手動でインスタンス化するのではなく、Springを使用して、この行の「carRepository。// ....」の後に発生する起動フェーズのどこかでインスタンス化します。

そのため、carRepositoryはそれ自体では静的ではなく、手動でインスタンス化されていないため、この正確な場所で使用することはできません。

ただし、CommandRunnerでは、returnが呼び出された時点で、CarRepositoryのインスタンスはSpringによって既に作成されており、Springの起動がすでに終了しているため、フィールドに自動配線されており、簡単に使用できます。

2 Shubh Aug 24 2020 at 17:46

Javaで許可されていない静的メソッドから直接非静的フィールドにアクセスしています

また、静的フィールドを作成することはできません @Autowired

だからあなたがこれをするなら

@Autowired
  private static CarRepository carRepository;

エラーはスローされませんが、無視されます。

1 AnkushSharma Aug 24 2020 at 18:44

メインメソッドは静的としてマークされており、静的メソッドから非静的メンバーにアクセスすることはできません。

これを解決するには、carRepositoryを静的としてマークする必要があります。ただし、静的フィールドは自動配線できないため、無視され、オブジェクトを取得できません。

その時点でスプリントの起動はすでに終了しており、Beanがインスタンス化されているため、コマンドランナーで機能します。