【问题标题】:Order in which fields in a bean are initialized初始化 bean 中的字段的顺序
【发布时间】:2013-03-26 01:29:52
【问题描述】:

我有一个这样的豆子:

@Component
@DependsOn("SomeType")
Class A{

@Autowired
SomeType one;

String two = one.someMethod();

int three;

}

In my application context xml, I have:

<bean id="two" class="a.b.c.SomeType"></bean>

<context:component-scan base-package="a.b.c"/>
<context:annotation-config/>

但是当 Spring 实例化 bean 时,它会抛出一个 NullPointerException。所以我想知道字段two 是否在字段one 之前初始化,导致NPE。谁能告诉我在 bean 中初始化字段的顺序是什么?

【问题讨论】:

    标签: java spring nullpointerexception in-class-initialization


    【解决方案1】:

    你的类A声明被编译成这个:

    class A {
        @Autowired 
        SomeType one;
        String two;
        int three;
    
        public A() {
            this.two = one.someMethod();
        }
    }
    

    因此,当 Spring 创建A 的实例以将SomeType 的实例注入其中时,它会调用A 的默认构造函数,因此您会得到NPE

    【讨论】:

    • 好的,谢谢你的回复,你能告诉我如果我在类中没有参数构造函数会发生什么,比如 public A(){}。还有你用来获取编译版本的工具或东西吗?
    • @maver1k 您的代码String two = one.someMethod(); 是一个实例变量初始化(stackoverflow.com/questions/1994218/…),无论您是否手动声明,编译器都会将其嵌入到构造函数中。您可以使用javap 查看编译器生成的结果字节码。
    【解决方案2】:

    首先我不得不说String two = one.someMethod();这行代码非常非常糟糕。然后让我解释一下 NPE 是如何发生的。 Spring在实例化bean时,首先实例化bean:A,然后尝试绑定字段one,此时可能无法实例化bean SomeType,所以Sping会将其标记为await to instant和然后继续绑定另一个字段,它移动到即时two,然后导致问题。

    【讨论】:

    • 谢谢。但是你说这是不好的编码习惯吗?我也错过了我拥有的重要部分“DependsOn”。我掩盖了首先创建 SomeType bean。
    • 说实话,如果你明白你使用Spring来维护所有的bean,那真的很糟糕,而且Spring不能保证bean实例化的顺序。而 这两个配置是重复的。
    • 即使我注释其中一个与“DependsOn”相关的 bean,SPring 也不能保证顺序?
    • 肯定可以保证依赖的bean会先被实例化,但不知何故,所有这些注解都是为了特殊目的,如果你必须使用它们,那就意味着代码中的某些东西不好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多