我有一个service-client项目,该项目在正常的spring应用程序中,而不是spring boot。它主要用于记录相关的东西。它包含Interceptor,loggingservice impl类和一些用于记录的模型类。我已在pom.xml中将此模块添加为对主应用程序的依赖关系,并且能够在主应用程序的服务层内注入并使用loggingService Bean。
在拦截器内自动连接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();
}
}
我的问题几乎与这篇文章Cannot Autowire Service in HandlerInterceptorAdapter相似,但其不同之处在于,它是从另一个模块引用拦截器,就像他们建议我尝试从该应用程序创建bean一样。但是现在面临的问题是
您的LoggingConfig
被标记为@Component
,而应将其标记为@Configuration
。不同之处在于,虽然允许在@Bean
上使用@Component
方法,但它以所谓的lite mode操作。意味着您不能使用方法引用来获取bean的实例(这是由于未创建任何特殊的代理)。这将导致仅创建LoggingInterceptor
的新实例,但它不是bean。
因此,简而言之,您正在做的工作等同于registry.addInterceptor(new LoggingInterceptor());
,它仅在Spring不知道的情况下创建一个实例。
[将LoggingConfig
标记为@Configuration
时,将创建一个特殊的代理,由于方法调用被拦截,该代理将使LoggingInterceptor
成为适当的单例bean。这将在Spring中注册Bean,您将可以调用该方法。