Spring BeanCreationException

1. Ikhtisar

Pada artikel ini, kita membahas Spring org.springframework.beans.factory.BeanCreationException - ini adalah pengecualian yang sangat umum dilontarkan saat BeanFactory membuat definisi kacang kacang dan mengalami masalah. Artikel ini akan membahas penyebab paling umum dari pengecualian ini beserta solusinya.

2. Penyebab: org.springframework.beans.factory.NoSuchBeanDefinitionException

Sejauh ini penyebab paling umum dari BeanCreationException adalah Spring yang mencoba memasukkan kacang yang tidak ada dalam konteksnya.

Misalnya, BeanA mencoba menyuntikkan BeanB :

@Component public class BeanA { @Autowired private BeanB dependency; ... }

Jika BeanB tidak ditemukan dalam konteksnya, maka pengecualian berikut akan dilemparkan (Kesalahan Membuat Bean):

Error creating bean with name 'beanA': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.baeldung.web.BeanB cpm.baeldung.web.BeanA.dependency; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.baeldung.web.BeanB] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Untuk mendiagnosis jenis masalah ini - pertama, pastikan kacang telah dideklarasikan:

  • baik dalam file konfigurasi XML menggunakan elemen
  • atau di kelas @Configuration Java melalui anotasi @Bean
  • atau dianotasi dengan: @Component , @Repository , @Service , @Controller dan pemindaian classpath aktif untuk paket itu

Juga periksa apakah file atau kelas konfigurasi benar-benar diambil oleh Spring dan dimuat ke dalam konteks utama.

3. Penyebab: org.springframework.beans.factory.NoUniqueBeanDefinitionException

Penyebab serupa lainnya untuk pengecualian pembuatan kacang adalah Spring mencoba menyuntikkan kacang menurut jenis - yaitu dengan antarmukanya - dan menemukan dua atau lebih kacang yang mengimplementasikan antarmuka itu dalam konteks.

Misalnya, BeanB1 dan BeanB2 mengimplementasikan antarmuka yang sama:

@Component public class BeanB1 implements IBeanB { ... } @Component public class BeanB2 implements IBeanB { ... } @Component public class BeanA { @Autowired private IBeanB dependency; ... }

Ini akan menyebabkan pengecualian berikut dilemparkan oleh pabrik kacang Spring:

Error creating bean with name 'beanA': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.baeldung.web.IBeanB com.baeldung.web.BeanA.b; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.baeldung.web.IBeanB] is defined: expected single matching bean but found 2: beanB1,beanB2

4. Penyebab: org.springframework.beans.BeanInstantiationException

4.1. Pengecualian Kustom

Baris berikutnya adalah kacang yang melempar pengecualian selama proses pembuatannya ; contoh yang disederhanakan untuk dengan mudah mencontohkan dan memahami masalahnya adalah melempar pengecualian dalam konstruktor kacang:

@Component public class BeanA { public BeanA() { super(); throw new NullPointerException(); } ... }

Seperti yang diharapkan, ini akan menyebabkan Spring gagal dengan cepat dengan pengecualian berikut:

Error creating bean with name 'beanA' defined in file [...BeanA.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.baeldung.web.BeanA]: Constructor threw exception; nested exception is java.lang.NullPointerException

4.2. java.lang.InstantiationException

Kemunculan lain yang mungkin dari BeanInstantiationException adalah mendefinisikan kelas abstrak sebagai kacang dalam XML; ini harus dalam XML, karena tidak ada cara untuk melakukan ini dalam file Java @Configuration dan pemindaian classpath akan mengabaikan kelas abstrak:

@Component public abstract class BeanA implements IBeanA { ... }

Dan definisi XML dari kacang:

Setup ini akan menghasilkan pengecualian serupa:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanA' defined in class path resource [beansInXml.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.baeldung.web.BeanA]: Is it an abstract class?; nested exception is java.lang.InstantiationException

4.3. java.lang.NoSuchMethodException

Jika kacang tidak memiliki konstruktor default dan Spring mencoba untuk membuat instance dengan mencari konstruktor tersebut, ini akan menghasilkan pengecualian runtime; sebagai contoh:

@Component public class BeanA implements IBeanA { public BeanA(final String name) { super(); System.out.println(name); } }

Ketika kacang ini diambil oleh mekanisme pemindaian jalur kelas, kegagalannya adalah:

Error creating bean with name 'beanA' defined in file [...BeanA.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.baeldung.web.BeanA]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.baeldung.web.BeanA.()

Pengecualian serupa, tetapi lebih sulit untuk didiagnosis, dapat terjadi ketika dependensi Spring pada classpath tidak memiliki versi yang sama ; jenis ketidakcocokan versi ini dapat menyebabkan NoSuchMethodException karena perubahan API. Solusi untuk masalah tersebut adalah memastikan semua pustaka Spring memiliki versi yang sama persis dalam proyek tersebut.

5. Penyebab: org.springframework.beans.NotWritablePropertyException

Namun kemungkinan lain adalah mendefinisikan kacang - BeanA - dengan referensi ke kacang lain - BeanB - tanpa memiliki metode penyetel yang sesuai di BeanA :

@Component public class BeanA { private IBeanB dependency; ... } @Component public class BeanB implements IBeanB { ... }

Dan Konfigurasi Spring XML:

Sekali lagi, ini hanya dapat terjadi dalam Konfigurasi XML , karena saat menggunakan Java @Configuration , kompilator akan membuat masalah ini tidak mungkin untuk direproduksi.

Tentu saja, untuk mengatasi masalah ini, penyetel perlu ditambahkan untuk IBeanB :

@Component public class BeanA { private IBeanB dependency; public void setDependency(final IBeanB dependency) { this.dependency = dependency; } }

6. Penyebab: org.springframework.beans.factory.CannotLoadBeanClassException

This exception is thrown when Spring cannot load the class of the defined bean – this may occur if the Spring XML Configuration contains a bean that simply doesn't have a corresponding class. For example, if class BeanZ doesn't exist, the following definition will result in an exception:

The root cause if the ClassNotFoundException and the full exception in this case is:

nested exception is org.springframework.beans.factory.BeanCreationException: ... nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.baeldung.web.BeanZ] for bean with name 'beanZ' defined in class path resource [beansInXml.xml]; nested exception is java.lang.ClassNotFoundException: com.baeldung.web.BeanZ

7. Children of BeanCreationException

7.1. The org.springframework.beans.factory.BeanCurrentlyInCreationException

One of the subclasses of BeanCreationException is the BeanCurrentlyInCreationException; this usually occurs when using constructor injection – for example, in a case of circular dependencies:

@Component public class BeanA implements IBeanA { private IBeanB beanB; @Autowired public BeanA(final IBeanB beanB) { super(); this.beanB = beanB; } } @Component public class BeanB implements IBeanB { final IBeanA beanA; @Autowired public BeanB(final IBeanA beanA) { super(); this.beanA = beanA; } }

Spring will not be able to resolve this kind of wiring scenario and the end result will be:

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?

The full exception is very verbose:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanA' defined in file [...BeanA.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.web.IBeanB]: : Error creating bean with name 'beanB' defined in file [...BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.web.IBeanA]: : Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanB' defined in file [...BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.web.IBeanA]: : Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?

7.2. The org.springframework.beans.factory.BeanIsAbstractException

This instantiation exception may occur when the Bean Factory attempts to retrieve and instantiate a bean which was declared as abstract; for example:

public abstract class BeanA implements IBeanA { ... }

Declared in the XML Configuration as:

Now, if we try to retrieve BeanA from the Spring Context by name – for example when instantiating another bean:

@Configuration public class Config { @Autowired BeanFactory beanFactory; @Bean public BeanB beanB() { beanFactory.getBean("beanA"); return new BeanB(); } }

This will result in the following exception:

org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'beanA': Bean definition is abstract

Dan stacktrace pengecualian lengkap:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanB' defined in class path resource [org/baeldung/spring/config/WebConfig.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public com.baeldung.web.BeanB com.baeldung.spring.config.WebConfig.beanB()] threw exception; nested exception is org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'beanA': Bean definition is abstract

8. Kesimpulan

Di akhir artikel ini, kita harus memiliki peta yang jelas untuk menavigasi berbagai penyebab dan masalah yang mungkin mengarah ke BeanCreationException di Spring, serta pemahaman yang baik tentang cara memperbaiki semua masalah ini.

Penerapan semua contoh pengecualian dapat ditemukan di proyek github - ini adalah proyek berbasis Eclipse, jadi semestinya mudah untuk mengimpor dan menjalankannya apa adanya.