Java 无法在 HandlerInterceptorAdapter 中自动装配服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18218386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:24:29  来源:igfitidea点击:

Cannot Autowire Service in HandlerInterceptorAdapter

javaspringspring-mvc

提问by dtrunk

I'm getting a NullPointerExceptionwhen trying to @Autowiremy @Service:

NullPointerException在尝试@Autowire我的时候得到了一个@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)

采纳答案by Sotirios Delimanolis

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

那是因为 Spring 没有管理您的PagePopulationInterceptor实例。您在下面的代码中自己创建它

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 PagePopulationInterceptorinstance since it's generated from a @Beanmethod. Spring will scan it for @Autowiredtargets and inject them.

这样,Spring 将管理PagePopulationInterceptor实例的生命周期,因为它是从@Bean方法生成的。Spring 将扫描它寻找@Autowired目标并注入它们。

This assumes that PagePopulationInterceptoris in a package to be @ComponentScaned.

这假设PagePopulationInterceptor在要@ComponentScan编辑的包中。