从另一个类调用方法时,自动装配的组件空指针异常

时间:2019-01-30 18:25:54

标签: java spring autowired

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

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

这是界面组件

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

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

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

这是使用自动装配组件的类

@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);

    }
}

2 个答案:

答案 0 :(得分: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);

    }
}

答案 1 :(得分:0)

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

@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);

    }
}