当前位置: 首页 > 知识库问答 >
问题:

无法在HandlerInterceptorAdapter中注入服务,正在获取NullPointerException

林炫明
2023-03-14

在拦截器中自动连接loggingService时,我正在获取NullPointerException。该bean在拦截器中不可用。但正如我所说的,它可以在主应用程序中注入和使用。
也不能在拦截器中使用@value读取属性。

这是我的拦截器课。

@Component
public class LoggingInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    LoggingService loggingService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
        loggingService.info("Am in prehandle");
        return true;
    }
}

这是我的配置类,我在其中向主应用程序注册拦截器

@Component
public class LoggingConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getLoginInterceptor());
    }

    @Bean
    public LoggingInterceptor getLoginInterceptor() {
        return new LoggingInterceptor();
    }

}

我的问题几乎类似于这篇文章不能自动连接HandlerInterceptorAdapter中的服务,但它的不同之处在于我引用了另一个模块中的拦截器,而正如他们所建议的那样,我试图从应用程序中创建bean。但我现在面临的问题是

  1. 在拦截器中注入loggingService时获得NullPointerException,但它在主应用程序中工作
  2. @value批注也返回null,无法从属性读取

共有1个答案

艾泉
2023-03-14

您有两种可能的解决方案。

  1. 将您的loggingconfig标记为@configuration而不是@copmponent
  2. 注入LoggingInterceptor而不是引用@bean方法

您的LoggingConfig标记为@component,而它应该标记为@configuration。不同的是,虽然允许在@component上使用@bean方法,但它以所谓的lite模式运行。这意味着您不能使用方法引用来获取bean的实例(这是因为没有创建特殊的代理)。这将导致创建LoggingInterceptor的一个新实例,但它不是bean。

简而言之,您所做的工作相当于registry.addInterceptor(new LoggingInterceptor());,它只是在Spring不知道的情况下创建一个实例。

当将loggingconfig标记为@configuration时,将创建一个特殊的代理,该代理将使logginginterceptor成为一个适当的单例bean,因为方法调用被拦截。这将在Spring中注册bean,并且您将能够调用该方法。

注意:实际上包含了LoggingInterceptor的两个实例,一个是由于其上的@component的缘故,另一个是通过@bean的缘故。删除@component

当您的LoggingInterceptor标记为@component时,Spring已经创建了一个实例(您在当前设置中实际创建了它的两个html" target="_blank">实例)。您可以将此实例注入到loggingconfig中。

@Component
public class LoggingConfig implements WebMvcConfigurer {

    private LoggingInterceptor loggingInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loggingInterceptor);
    }
}

这样,您就可以删除@bean方法,因为您会将适当的方法注入到LoggingConfig类中。在这种情况下,类也可以保持为@component。但我还是建议使用@configuration来正确地构造它。

注意:如果您使用的是最近的Spring版本,则可以使用@configuration(ProxyBeanMethods=false)。这将生成一个lite-configuration(就像@component),但它仍然正确地标记为配置类。

 类似资料:
  • 问题内容: 我想将服务注入app.config,以便可以在调用控制器之前检索数据。我这样尝试过: 服务: 配置: 但是我得到这个错误: 错误:未知提供程序:EditorApp的dbService 如何更正设置并注入此服务? 问题答案: Alex提供了无法执行您要尝试执行的操作的正确原因,因此+1。但是您遇到此问题是因为您没有完全使用解决方案的设计方式。 接受服务或函数的字符串,返回要注入的值。由于

  • 我有一个简单的spring cloud项目,它包含4个服务: 配置:8888 登记处(尤里卡):8761 网关(zuul):8080 服务-1:9527 在此输入图像说明 如果将项目部署在localhost中, 我可以在没有Docker的情况下通过zuul成功获取Service-1的api: http://localhost:8080/service-1/test 但当我使用docker进行部署时

  • 我正在获取O并且从未进行成功的Hibernate连接测试,在学习了本教程“JasperReports with hibernate-module1”和JasperReports with hibernate-module2之后,弹出一个错误,说“Could not parse mapping document from resource com/report/mappings/department

  • 我是android开发的新手。我正在开发一个简单的应用程序,其中包含1个活动,1个广播接收器和1个通知服务。有些警报设置在活动中,我想在设备启动/重启时重新设置它们。 下面是我在MainActivity中的代码: 我从活动中设置的警报中正确地获取所有通知。但获取NullpointerException 这是我从意图中读到额外内容的地方。我错过了什么?任何帮助都很感激。 附言。所有必要的权限都在清单

  • 我有一个有状态的会话作用域(CDI)EJB,它保存有关用户会话的信息。 现在,我想从一个 我从webapp直接访问EJB(使用注入)到我为JSF使用的bean中(它们也是CDI管理的bean)。 我面临的问题是,似乎与JSF bean处于不同的“会话范围”。创建了两个实例;一个从JSF实例化,另一个从HttpSessionListener实例化。 我尝试通过注入实例注入bean 这个bug报告建议

  • 问题内容: authService.getLoggedin()返回false或true取决于用户是否登录。然后,我想不允许他们进入网址,如果不允许的话。 但是我收到此错误:错误:[$ injector:modulerr]由于以下原因无法实例化模块WikiApp:[$ injector:unpr]未知提供程序:authService 问题答案: 在配置阶段,您只能要求提供程序($ routeProv