AutowiredSpringbean在抽象父类中为空

tvmytwxo  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(317)

我有一个bean,负责从配置文件加载项目设置,并使它们可用于可能需要它们的任何其他对象:

@Component
public class ProjectSettings extends Settings{[...]}

现在,我有一堆组件类,它们通过多个步骤扩展了一个抽象类,我想在其中使用这个bean:

@Component
public class SomeDataDbEditor extends MongoDbEditor<SomeData> {[...]}

public abstract class MongoDbEditor<T extends MongodbEntryInterface> extends MongoDbTypedAccessor<T>{[...]}

public abstract class MongoDbTypedAccessor<T extends MongodbEntryInterface> extends MongoDbAccessor {[...]}

public abstract class MongoDbAccessor {
    @Autowired
    protected ProjectSettings projectSettings;

    public MongoDbAccessor() throws DatabaseNotConnectedException {
        String databaseName = projectSettings.getMongodbDatabaseName();
        [...]
}

根据我的理解,这应该是可行的,因为@autowired字段是受保护的,因此可以从@component类中看到 SomeDataDbEditor . 但是,我得到了一个例外:

java.lang.IllegalStateException: Failed to load ApplicationContext
[...]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.company.project.module.some_data.database.accessor.SomeDataDbEditor]: Constructor threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:217)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:310)
    ... 124 more
Caused by: java.lang.NullPointerException
    at io.company.project.module.database.accessor.MongoDbAccessor.<init>(MongoDbAccessor.java:26)
    at io.company.project.module.database.accessor.MongoDbTypedAccessor.<init>(MongoDbTypedAccessor.java:20)
    at io.company.project.module.database.accessor.MongoDbEditor.<init>(MongoDbEditor.java:19)
    at io.company.project.module.some_data.database.accessor.SomeDataDbEditor.<init>(SomeDataDbEditor.java:17)

…引用 MongoDbAccessor.<init>(MongoDbAccessor.java:26) 线路是 String databaseName = projectSettings.getMongodbDatabaseName(); 现在,我已经确认 projectSettings 在这种情况下,字段实际上是空的。但是,我也能够确认如果我尝试访问 ProjectSettings 咖啡豆 SomeDataDbEditor ,这样就可以工作了,并且bean得到了正确的示例化。
我知道在这一点上,一个可能的解决方案是使用它并手动传递 ProjectSettings bean到父类,但这可能会挫败首先使用依赖注入的意义。另外,我必须调整,像,真的,真的很多类,如果可能的话,我想避免。
那么,有没有人知道为什么会发生这种情况,以及我能做些什么来对付它?

b09cbbtk

b09cbbtk1#

如果使用字段注入(字段上的自动连线),则不能在构造函数中使用这些字段,因为spring只能在构造对象之后(即在所有构造函数完成之后)注入依赖项。
为了避免这种情况,您必须更改为构造函数注入,或者在一个用postconstruct注解的单独方法中执行初始化工作,就像您在构造函数中所做的那样:

@javax.annotation.PostConstruct
public void initialize() {

}

但是,如果您能够将代码更改为构造函数注入,我(以及spring世界中的许多其他人)强烈建议您使用它,因为它确实可以防止此类问题。

相关问题