我有一个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到父类,但这可能会挫败首先使用依赖注入的意义。另外,我必须调整,像,真的,真的很多类,如果可能的话,我想避免。
那么,有没有人知道为什么会发生这种情况,以及我能做些什么来对付它?
1条答案
按热度按时间b09cbbtk1#
如果使用字段注入(字段上的自动连线),则不能在构造函数中使用这些字段,因为spring只能在构造对象之后(即在所有构造函数完成之后)注入依赖项。
为了避免这种情况,您必须更改为构造函数注入,或者在一个用postconstruct注解的单独方法中执行初始化工作,就像您在构造函数中所做的那样:
但是,如果您能够将代码更改为构造函数注入,我(以及spring世界中的许多其他人)强烈建议您使用它,因为它确实可以防止此类问题。