spring 创建bean失败的原因很多种!

感谢https://blog.csdn.net/zzg1229059735/article/details/51320218

Spring中常见的bean创建异常

1. 概述

    本次我们将讨论在spring中BeanFactory创建bean实例时经常遇到的异常

org.springframework.beans.factory.BeanCreationException,下面我们将讨论并再现这些异常,同时给出解决方案。

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

    到目前为止最常见的导致BeanCreationException 莫过于注入一个上下文中不存在的bean。

例如:BeanA尝试注入BeanB

@Component

public class BeanA {

    @Autowired

    private BeanB dependency;

    ...

}

1

2

3

4

5

6

7

如果spring上下文中不存在BeanB,那么下面的异常将会抛出

Error creating bean with name 'beanA': Injection of autowired dependencies failed;

nested exception is org.springframework.beans.factory.BeanCreationException:

Could not autowire field: private org.baeldung.web.BeanB org.baeldung.web.BeanA.dependency;

nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:

No qualifying bean of type [org.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)}

1

2

3

4

5

6

7

解决这种类型的问题——首先, 确保bean已经声明了

  在XML配置文件使用< bean / >元素

  或通过@bean注释Java @ configuration类

  或注释:@Component,@Repository,@Service,@Controller和类路径是否扫描包中。

同时检查配置文件或类文件是否真的已经被spring装载到上下文中。

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

另一个比较类似的异常情况,当你尝试让spring使用接口名来时创建一个bean时,但是发现它有两个或多个实现

例如:BeanB1 和BeanB2都实现了同一个接口

@Component

public class BeanB1 implements IBeanB { ... }

@Component

public class BeanB2 implements IBeanB { ... }

@Component

public class BeanA {

    @Autowired

    private IBeanB dependency;

    ...

}

1

2

3

4

5

6

7

8

9

10

11

12

这将导致BeanFactory抛出一下异常:

Error creating bean with name 'beanA': Injection of autowired dependencies failed;

nested exception is org.springframework.beans.factory.BeanCreationException:

Could not autowire field: private org.baeldung.web.IBeanB org.baeldung.web.BeanA.b;

nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:

No qualifying bean of type [org.baeldung.web.IBeanB] is defined:

expected single matching bean but found 2: beanB1,beanB2

1

2

3

4

5

6

4. Cause:org.springframework.beans.BeanInstantiationException

4.1. Custom Exception

下面例子是抛出在其创建过程异常;简化的样例很容易体现和理解问题出现构造函数中,并抛出一个异常:

@Component

public class BeanA {

    public BeanA() {

        super();

        throw new NullPointerException();

    }

    ...

}

1

2

3

4

5

6

7

8

9

不出所料,spring很快的抛出以下异常:

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 [org.baeldung.web.BeanA]:

Constructor threw exception;

nested exception is java.lang.NullPointerException

1

2

3

4

5

4.2. java.lang.InstantiationException

另一种可能发生BeanInstantiationException是在xml配置中使用抽象类定义bean。

这种只可能发生在xml配置文件中,

因为没有办法在Java@Configuration文件和classpath扫描会忽略抽象类来做到这一点:

@Component

public abstract class BeanA implements IBeanA { ... }

1

2

<bean id="beanA" class="org.baeldung.web.BeanA" />

1

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 [org.baeldung.web.BeanA]:

Is it an abstract class?;

nested exception is java.lang.InstantiationException

1

2

3

4

5

6

7

4.3. java.lang.NoSuchMethodException

如果一个bean类没有默认的构造方法,spring在创建bean实例时将会抛出如下运行时异常:

@Component

public class BeanA implements IBeanA {

    public BeanA(final String name) {

        super();

        System.out.println(name);

    }

}

1

2

3

4

5

6

7

8

如果该类的类路径在扫描路径下,将会抛出如下失败:

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 [org.baeldung.web.BeanA]:

No default constructor found;

nested exception is java.lang.NoSuchMethodException: org.baeldung.web.BeanA.<init>()

1

2

3

4

5

类似的异常,但难以诊断,当类路径的Spring的依赖并不具有相同的版本,可能会发生异常;这种版本不兼容,可能会导致因API变化的NoSuchMethodException。这种问题的解决方案是确保所有Spring库在该项目中的精确相同的版本。

5. Cause:org.springframework.beans.NotWritablePropertyException

然而,另一种可能性是你定义了一个bean:BeanA同时引用了另一个bean:BeanB但是BeanA中却没有相应的setter方法

@Component

public class BeanA {

    private IBeanB dependency;

    ...

}

@Component

public class BeanB implements IBeanB { ... }

1

2

3

4

5

6

7

配置文件

<bean id="beanA" class="org.baeldung.web.BeanA">

    <property name="beanB" ref="beanB" />

</bean>

1

2

3

此外需要说明的是,这种情况只可能发生在xml配置文件,因为当你使用@Configuration时,spring容器会避免这种情况的发生。

当然,为了解决这个问题,需要为IBeanB添加setter方法

@Component

public class BeanA {

    private IBeanB dependency;

    public void setDependency(final IBeanB dependency) {

        this.dependency = dependency;

    }

}

1

2

3

4

5

6

7

8

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

当spring加载不到bean对应的类文件时,这种异常将会被抛出。这种情况很有可能发生在当配置文件中的类路径全称找不到对应文件时。

<bean id="beanZ" class="org.baeldung.web.BeanZ" />

1

抛出ClassNotFoundException的根本原因

nested exception is org.springframework.beans.factory.BeanCreationException:

...

nested exception is org.springframework.beans.factory.CannotLoadBeanClassException:

Cannot find class [org.baeldung.web.BeanZ] for bean with name 'beanZ'

defined in class path resource [beansInXml.xml];

nested exception is java.lang.ClassNotFoundException: org.baeldung.web.BeanZ

1

2

3

4

5

6

7

7. Children of BeanCreationException

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

BeanCurrentlyInCreationException是BeanCreationException的一个子类,经常在发生在错误的使用构造方法注入bean。

例如:循环依赖的情况

@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;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Spring将不能够解决这种场景,最终导致

org.springframework.beans.factory.BeanCurrentlyInCreationException:

Error creating bean with name 'beanA':

Requested bean is currently in creation: Is there an unresolvable circular reference?

1

2

3

完整的异常信息非常丰富

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 [org.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 [org.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 [org.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?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

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

public abstract class BeanA implements IBeanA {

  ...

}

1

2

3

在xml配置中声明如下:

<bean id="beanA" abstract="true" class="org.baeldung.web.BeanA" />

1

现在,如果试图从spring上线文中获取BeanA实例,例如:

@Configuration

public class Config {

    @Autowired

    BeanFactory beanFactory;

    @Bean

    public BeanB beanB() {

        beanFactory.getBean("beanA");

        return new BeanB();

    }

}

1

2

3

4

5

6

7

8

9

10

11

将会抛出以下异常:

org.springframework.beans.factory.BeanIsAbstractException:

Error creating bean with name 'beanA': Bean definition is abstract

1

2

全部异常栈信息:

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 org.baeldung.web.BeanB org.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

1

2

3

4

5

6

7

8

8. 总结

  最后,我们应该有一个清晰的认识:什么情况会导致什么样的BeanCreationException,同时知道如何很好的解决该问题。

这些异常的再现实例可以在 the github project 上找到,下载后用eclipse导入即可。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容