Cannot Autowire Service in HandlerInterceptorAdapter

JavaSpringSpring Mvc

Java Problem Overview


I'm getting a NullPointerException when trying to @Autowire my @Service:

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;
	}
}

EDIT: Here's the Stacktrace:

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)

Java Solutions


Solution 1 - Java

That's because Spring isn't managing your PagePopulationInterceptor instance. You are creating it yourself in the below code

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

change that to

@Bean
public PagePopulationInterceptor pagePopulationInterceptor() {
    return new PagePopulationInterceptor();
}

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

In this way, Spring will manage the lifecycle of the PagePopulationInterceptor instance since it's generated from a @Bean method. Spring will scan it for @Autowired targets and inject them.

This assumes that PagePopulationInterceptor is in a package to be @ComponentScaned.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondtrunkView Question on Stackoverflow
Solution 1 - JavaSotirios DelimanolisView Answer on Stackoverflow