gpt4 book ai didi

java - @Autowired 请求处理失败;嵌套异常是 java.lang.NullPointerException

转载 作者:行者123 更新时间:2023-11-29 04:13:44 24 4
gpt4 key购买 nike

我正在尝试通过使用从现有 Spring 应用程序中分离依赖项Spring @Bean 在配置类中,@Autowired 在使用它的类中。

下面是主要的配置类:

@Configuration
@ComponentScan(basePackages = {"com.example"})
@EnableWebMvc
public class DataLoadConfig extends WebMvcConfigurerAdapter {

@Bean
ActivitiesFeed activityFeed() {
HashMap<Integer, Object> temp = new HashMap<Integer, Object>();
return new ActivitiesFeed(temp);
}

...

这里是依赖的使用方式:

public class ActivitiesLoad {

// ADDED
@Autowired
ActivitiesFeed activityFeed;

public ActivitiesLoad(String loadType, int personCode, String outputFilter, int outputNumber) {

...

// REMOVED - this approach didn't throw any errors though
// HashMap<Integer, Object> temp = new HashMap<Integer, Object>();
// ActivitiesFeed activityFeed = new ActivitiesFeed(temp);

// This dependency is now @Autowired in
feed = activityFeed.getActivities();
...

但是,我现在收到以下错误:

SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/DataLoads] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at ac.uk.strath.t4.dataload.pure.activities.ActivitiesLoad.<init>(ActivitiesLoad.java:66)
at ac.uk.strath.t4.dataload.controller.DataLoadController.pureActivities(DataLoadController.java:149)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
...

查看原始初始化代码,此运行没有任何问题,所以我知道依赖项有效但想知道我是否错误地实现了注入(inject)。

顺便说一下,我不拥有 ActivitiesFeed 源,所以我无法将任何 @Components 附加到该类,所以我选择将它作为 @Bean 放入应用程序配置类 (DataLoadConfig) 中。

注意:我还尝试将 ActivitiesLoad 构造函数代码放入 run(...) 方法中,只是将它包含在我试图从构造函数中访问依赖项这一事实的问题中,但它只是给出了我同样的错误。理想情况下,我宁愿暂时将代码留在构造函数中,因为它是其他人的代码,并且不想在这个阶段冒险破坏太多:)

更新

我试过添加一个@PostConstruct 方法,但还是一样的问题。然后,我将 activityFeed 属性设为私有(private),就像我在示例中看到的那样,但都是一样的。

public class ActivitiesLoad {

@Autowired
private ActivitiesFeed activityFeed;

private String loadType;
private int personCode;
private String outputFilter;
private int outputNumber;

public ActivitiesLoad(String loadType, int personCode, String outputFilter, int outputNumber) {
log.debug("Starting pure activities data load");
this.loadType = loadType;
this.personCode = personCode;
this.outputFilter = outputFilter;
this.outputNumber = outputNumber;
}

@PostConstruct
public void init() {
log.debug("Starting pure activities data load @PostConstruct");
log.debug(activityFeed); // outputs: null
...

更新 2

在这里,我将依赖项排除在构造函数之外,而是将其放入它自己的 init 方法中,并在创建 ActivityLoad 实例后调用它。但是,我仍然看到 NullPointerException 的问题。

ActivityLoad 的实例化(现在使用 init 方法,在创建实例后调用):

...
ActivitiesLoad activitiesLoad = new ActivitiesLoad();
activitiesLoad.init(loadType, personCode, typeFilter, outputLimit);
...

这是包含新方法的 ActivityLoad 类

@Component
public class ActivitiesLoad {

@Autowired
private ActivitiesFeed activityFeed;

public void init(String loadType, int personCode, String outputFilter, int outputNumber) {
log.debug(activityFeed); // outputs: null

最佳答案

您需要记住两件事。

i) 如果您使用 new 关键字创建类实例,那么特定实例将不会被 Spring 管理,这意味着它不会 Autowiring bean你在链中请求。因此,从一开始,ActivitiesFeed activityFeed 将始终在 ActivitiesLoad 实例中为 null,这些实例是通过使用 new ActivitiesLoad(...)

ii) 第二点是关于您的更新。正如其他答案所建议的那样,您试图通过类构造函数中的注入(inject) bean 调用方法。这在任何 DI 框架中都不起作用,因为构造函数仅用于初始化字段引用而不是调用它们。这就是为什么您需要 @PostConstruct,它在 bean 初始化/构造函数成功完成后由 Spring 容器调用,因此 bean 引用将获得正确的实例。

所以这给您留下了 2 个可能的选择:

a. 通过将 ActivitiesLoad 正确地 Autowiring 为原型(prototype)并传递所需的状态来维护上下文。

b. 重构 ActivitiesLoad 以完全不保留上下文,更改构造函数以保留默认构造函数并实现所有逻辑以及所需的参数(上下文) 在此方法中。然后你可以通过使用 @Autowire

在 Controller 中 Autowiring 这个 bean

关于java - @Autowired 请求处理失败;嵌套异常是 java.lang.NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53594038/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com