【问题标题】:Autowired field is null in RestControllerRestController 中的 Autowired 字段为空
【发布时间】:2021-08-10 15:25:39
【问题描述】:

我有一个包含多个模块的项目,我的目标是在其他模块中重用“核心”模块中定义的服务。 例如,模块“批处理”能够通过加载应用程序上下文类(通过 AnnotationConfigApplicationContext)来重用“核心”模块(声明为@Autowired)中定义的方法,该类加载和连接“核心”服务。到目前为止一切顺利。

当我想在我的“休息控制器”模块中做同样的事情时,问题就出现了。就像在 'batch' 模块中一样,'core' 服务被声明为 @Autowired,但是当控制器尝试使用它时,会显示以下异常:

java.lang.NullPointerException itix.rest.itixrestservice.RestRessourceController.getRealMethod(RestRessourceController.java:40) sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:498) org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)

我还没有得到的东西,我认为是失败的原因,是如何在“休息控制器”上下文中加载应用程序上下文(以及连接我的服务)。

这个“休息控制器”模块只需要暴露一些端点,视图部分被委托给另一个模块,该模块将检索并显示端点内容。控制器代码如下:

@Component 
@ComponentScan(basePackages = {"itix.core.service","itix.rest.itixrestservice"}) 
@Path("/controller") 
public class RestRessourceController extends AnnotationConfigApplicationContext {

@Autowired
MatchService matchService;

@GET
@Path("getReal")
@Produces(MediaType.APPLICATION_JSON)
public ResponseEntity<List<Match>> getReal() {
    List<Match> allMatches = matchService.getAllMatches();
    return ResponseEntity.ok(allMatches);
}

服务声明如下:

@Service 
@Transactional(readOnly = true) public class MatchServiceImpl implements MatchService {

@Autowired
MatchDao matchDao;

还有道:

@Repository public class MatchDaoImpl implements MatchDao {

@Autowired
private SessionFactory sessionFactory;

这是对引发错误的控制器的调用:

http://localhost:8889/itix-rest-service/rest/controller/getReal

顺便说一句,对不调用自动装配服务的不同方法的相同调用工作正常。

我找到了一些使用 spring MVC 的信息,但这不是我想要实现的。 我错过了什么?有什么我应该看的链接吗?

【问题讨论】:

  • 我认为您需要在您的问题中添加一些代码(和 pom),否则很难通过查看没有任何代码上下文的堆栈跟踪来帮助您。
  • 请贴一些代码。我们需要知道控制器中使用了哪些注解。你的上下文是什么样的?你是如何使用自动装配的?也许发布修改后的代码(隐藏您不想分享的任何细节)以便我们为您提供帮助。
  • 我已用所需信息更新了问题。请让我知道是否需要其他任何东西?
  • 您有该服务的源代码吗?它应该是“Spring compatible”吗?
  • 我已经用 service 和 dao 更新了这个问题。够了吗?

标签: java spring autowired spring-restcontroller


【解决方案1】:

(免责声明:我正在使用所提供的信息)。

默认情况下,@Autowired MatchService matchService 在 Spring 中永远不会导致 NullPointerException,因为 @Autowired 的默认行为是非可选的 - 应该已经提出 BeanNotFoundException

这表明@Autowired 在您的控制器类中根本不起作用。 查看正在使用 @ComponentScanextends AnnotationConfigApplicationContext 的控制器,我猜您正在混合控制器和主 Spring Boot 类,这是无法工作的。主 Spring Boot 类不能 @Autowire bean,因为它用于初始化 Spring Boot 本身,因此不是托管 bean。

删除 @ComponentScanextends AnnotationConfigApplicationContext 并移至单独的主类应该可以解决您的问题:

@SpringBootApplication
@ComponentScan(basePackages = {"itix.core.service","itix.rest.itixrestservice"}) 
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

即使您不使用 Spring Boot,解决方案也应该类似 - 不要将您的控制器和 AnnotationConfigApplicationContext 类混用。

【讨论】:

  • 感谢您的回答,解决了一些问题。我仍然不明白的是 Application 类和控制器(定义 @Paths 的类)之间的链接。我已将我的项目打包为战争以公开端点。在战争部署的哪一步调用应用程序的 main() 来检测 bean?
  • 您可以在此处阅读有关 tomcats servlet 检测的信息:mulesoft.com/tcat/tomcat-deploy-procedures
猜你喜欢
  • 2019-08-10
  • 1970-01-01
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
相关资源
最近更新 更多