Не удается автопровести сервис в HandlerInterceptorAdapter
Проблема с NullPointerException
при использовании @Autowired
в Spring
Я получаю ошибку NullPointerException
, когда пытаюсь использовать аннотацию @Autowired
для внедрения моего сервиса в класс-перехватчик:
public class PagePopulationInterceptor extends HandlerInterceptorAdapter {
private @Autowired MyService service;
public @Override void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mav) {
service.savePageView(IPUtils.toLong(request.getRemoteAddr()), request.getRequestURI(), request.getHeader("User-Agent"));
mav.addObject("counter", service.getCounter());
}
}
Также вот конфигурационный класс:
@Configuration
@ComponentScan(basePackages = "com.mycompany", excludeFilters = { @ComponentScan.Filter(Configuration.class) })
@PropertySource("classpath:application.properties")
@EnableTransactionManagement
@EnableWebMvc
public class MyConfig extends WebMvcConfigurerAdapter {
public @Override void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new PagePopulationInterceptor());
}
}
И сервис, который я пытаюсь использовать:
@Service
@Transactional
public class MyService {
private @Autowired PageViewDao pageViewDao;
public class Counter {
private long total;
private long today;
private long yesterday;
private long now;
// Getters and setters
}
public void savePageView(long ip, String visitPage, String userAgent) {
PageView obj = new PageView();
obj.setVisitDate(new Date());
obj.setUserAgent(userAgent);
obj.setPage(visitPage);
obj.setIp(ip);
pageViewDao.saveOrUpdate(obj);
}
public Counter getCounter() {
Counter ret = new Counter();
// populate Counter members
return ret;
}
}
Стек вызовов
Вот стек вызовов, который я получаю:
java.lang.NullPointerException
com.mycompany.util.PagePopulationInterceptor.postHandle(PagePopulationInterceptor.java:22)
org.springframework.web.servlet.HandlerExecutionChain.applyPostHandle(HandlerExecutionChain.java:149)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:934)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Вопрос
Почему поле service
оказывается null
, и как мне исправить эту ошибку? Как можно правильно выполнить внедрение зависимостей в данном случае?
1 ответ(ов)
Это происходит потому, что Spring не управляет вашим экземпляром PagePopulationInterceptor
. Вы создаете его самостоятельно в приведенном ниже коде:
public @Override void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new PagePopulationInterceptor());
}
Измените это на:
@Bean
public PagePopulationInterceptor pagePopulationInterceptor() {
return new PagePopulationInterceptor();
}
public @Override void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(pagePopulationInterceptor());
}
Таким образом, Spring будет управлять жизненным циклом экземпляра PagePopulationInterceptor
, поскольку он создается из метода с аннотацией @Bean
. Spring будет сканировать его на наличие целей, помеченных аннотацией @Autowired
, и инъектировать их.
Это предполагает, что PagePopulationInterceptor
находится в пакете, который будет просканирован с помощью @ComponentScan
.
Передача нескольких параметров в REST API - Spring
Как реализовать пагинацию в Spring MVC 3 [закрыто]
Разница между @Inject и @Autowired в Spring Framework: когда и что использовать?
Создание репозитория Spring без сущности
Закодированный пароль не выглядит как BCrypt