【问题标题】:Autowired component null pointer exception when calling method from another class从另一个类调用方法时自动装配组件空指针异常
【发布时间】:2019-01-30 18:25:54
【问题描述】:

我有一个带有 Autowired 组件和方法的类。如果我直接调用该方法,它工作正常。但是,如果对该方法的调用来自另一个类,那么在使用 Autowired 组件的行中会出现 java.lang.NullPointerException 错误。 Autowired 组件是一个充当代理的接口组件。我已经为接口组件和自动装配组件尝试了不同的注释,但仍然出现错误。

如果直接调用该方法,我不明白为什么 Autowired 组件不为空,但如果从另一个类调用它则为空。

这是界面组件

@FeignClient(name = "authentication-server", url = "localhost:8010")
public interface AuthenticationProxy {

    @GetMapping("/headers")
    public HttpEntity<String> retrieveHeaders();

    @GetMapping("/auth-token")
    public AuthorizationTokenBean retrieveToken();

这是使用 Autowired 组件的类

@RestController
public class UserController {

    @Autowired
    private AuthenticationProxy authenticationProxy;

    @PostMapping("/user/create")
    public UserResponseBean createUser(ValuesBean userValues) {

        UserCreateRequestBean bodyBean = new UserCreateRequestBean();
        ValuesBean valuesBean = new ValuesBean();

        bodyBean.setValues(userValues); 

        // This line triggers the null pointer error 
        // (only if method called from another class)
        String token = authenticationProxy
            .retrieveToken()
            .getAuthorizationToken();

        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", token);
        headers.add("Content-type", "application/json");
        headers.add("accept", "application/json");

        HttpEntity<Object> requestEntity =
                new HttpEntity<>(bodyBean, headers);

        ResponseEntity<String> responseEntity = new RestTemplate().exchange(
                "https://api.acme.com/user/create",
                HttpMethod.POST,
                requestEntity,
                String.class
        );

        String output = responseEntity.getBody();
        Gson gson = new Gson();
        return gson.fromJson(output,UserResponseBean.class);

    }
}

这是调用方法所在的类

@RestController
public class TestController {

    @GetMapping("/test/user/create")
    public void testUserCreate() {

        ValuesBean valuesBean = new ValuesBean();
        valuesBean.setDate_of_birth("1917-05-16");
        valuesBean.setFirst_name("Juan");
        valuesBean.setLast_name("Rulfo");
        valuesBean.setGender("Male");
        valuesBean.setOccupation("Escritor");

    UserController testUser = new USerController();
    testUSer.createUser(valuesBean);

    }
}

【问题讨论】:

  • 您是否将@EnableFeignClients 添加到您的应用程序类中?
  • 是:@EnableFeignClients("com.acme.apimiddleware.acmetoy") public class UsersApplication { public static void main(String[] args) { SpringApplication.run(UsersApplication.class, args); } }

标签: java spring autowired


【解决方案1】:

首先:这个世界上没有魔法。

依赖注入只有依赖注入框架才有可能,Spring提供了其中之一。

使用实例化类时:

UserController testUser = new UserController();

您没有使用任何依赖注入框架,只使用纯 Java 对象实例化。 所以你不能指望@Autowired 字段会被魔法填充。

下面的代码可以在 java 对象实例中填充 @Autowired 字段:

@Autowired private ApplicationContext applicationContext;

...

UserController bean = new UserController();
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean( bean );

但我认为您的目标是使用 Spring 已经实例化的 UserController 而不是您创建的新实例。所以下面的代码可能就是你真正想要的:

@RestController
public class TestController {

    @Autowired private UserController testUser;

    @GetMapping("/test/user/create")
    public void testUserCreate() {

        ValuesBean valuesBean = new ValuesBean();
        valuesBean.setDate_of_birth("1917-05-16");
        valuesBean.setFirst_name("Juan");
        valuesBean.setLast_name("Rulfo");
        valuesBean.setGender("Male");
        valuesBean.setOccupation("Escritor");

        testUser.createUser(valuesBean);

    }
}

【讨论】:

  • 谢谢@Mumrah81,你说得对:我必须自动装配我想使用的组件,而不是手动创建一个实例
【解决方案2】:

解决了! 问题是我手动实例化了从外部类调用的组件,而不是自动装配它。

@RestController
public class TestController {

    @Autowired
    UsersController usersController;

    @GetMapping("/test/user/create")
    public void testPolicyholderCreate() {

        ValuesBean valuesBean = new ValuesBean();
        valuesBean.setDate_of_birth("1917-05-16");
        valuesBean.setFirst_name("Juan");
        valuesBean.setLast_name("Rulfo");
        valuesBean.setGender("Male");
        valuesBean.setOccupation("Escritor");

    usersController.createUser(valuesBean);

    }
}

【讨论】:

    猜你喜欢
    • 2021-06-05
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 2020-06-12
    • 1970-01-01
    • 2012-02-21
    • 2015-11-16
    • 2017-11-20
    相关资源
    最近更新 更多