自动装配空指针异常 [英] Autowired Null Pointer Exception
问题描述
我有一个过滤器可以将请求保存到数据库.但是我在自动装配字段上收到 NullPointerException:inboundRequestLogStore.
I have a filter to save requests to DB. But I get NullPointerException on autowired field: inboundRequestLogStore.
我已经尝试过 在 Filter bean 类中使用一些 bean 的建议? (我已将 SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext()); 添加到过滤器初始化方法并在我的 root-context.xml 中定义了一个 bean)
现在它可以工作了对于 RequestLogFilter 类.但是,在 InboundRequestLogStore 类中,我有另一个自动装配的归档 logService 将我的实体保存到数据库,现在我得到 NullPointerEception.为什么我有 NPE 以及如何解决它?我在项目的其他部分有相同的服务/组件,它们自动装配服务没有任何问题.我只使用过滤器有问题.
I've tried the suggestion from Using some beans in Filter bean class? (I've added SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext()); to the filter init method and defined a bean in my root-context.xml )
and now it works for the RequestLogFilter class. But, in the InboundRequestLogStore class I have another autowired filed logService to save my entity to DB and now at this point I get NullPointerEception. Why I have the NPE and how to resolve it? I have the same services/components in another parts of my project and they autowires services without any problems. I have troubles only using the filter.
@Component
public class RequestLogFilter implements Filter {
@Autowired
private InboundRequestLogStore inboundRequestLogStore;
public RequestLogFilter() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext());
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest requestToCache = new ContentCachingRequestWrapper((HttpServletRequest) request);
HttpServletResponseCopier responseCopier = new HttpServletResponseCopier((HttpServletResponse) response);
chain.doFilter(request, responseCopier);
responseCopier.flushBuffer();
if (request.getAttribute(InboundRequestAspect.INBOUND_LOG_MARKER) != null) {
InboundRequestLogRecord logRecord = new InboundRequestLogRecord();
setters....
inboundRequestLogStore.add(logRecord);
}
}
}
--
@Component("inboundRequestLogStore")
public class InboundRequestLogStore implements InitializingBean {
private ConcurrentLinkedQueue<InboundRequestLogRecord> queue = new ConcurrentLinkedQueue<>();
@Autowired
private LogService logService;
@Override
public void afterPropertiesSet() throws Exception {
reseterPool = new ScheduledThreadPoolExecutor(1);
reseterPool.scheduleWithFixedDelay(new LogRequestSaveQueueTask(), startupDelay, sleepTimeout, TimeUnit.SECONDS);
}
public InboundRequestLogStore() {
}
public void add(InboundRequestLogRecord logRequest) {
queue.add(logRequest);
}
private class LogRequestSaveQueueTask implements Runnable {
@Override
public void run() {
try {
if (queue.size() > 0) {
List<InboundRequestLogRecord> logRequestList = new ArrayList<>();
InboundRequestLogRecord obj;
while((obj = queue.poll()) != null) {
logRequestList.add(obj);
}
if (!logRequestList.isEmpty()) {
logService.save(logRequestList);
}
}
} catch(Exception e) {
logger.error(e.getMessage(), e);
}
}
}
}
堆栈跟踪
java.lang.NullPointerException: null
at com.my.project.services.log.InboundRequestLogStore$LogRequestSaveQueueTask.run(InboundRequestLogStore.java:71) [classes/:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_131]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_131]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]
-
<context:component-scan base-package="com.my.project" />
-
<bean id="inboundRequestLogStore" class="com.my.project.services.log.InboundRequestLogStore" />
如果使用 DelegatingFilterProxy 那么我得到 p>
If use DelegatingFilterProxy then I get
SEVERE: Servlet.service() for servlet [appServlet] in context with path [] threw exception
java.lang.NullPointerException
at com.my.project.config.filter.RequestLogFilter.doFilter(RequestLogFilter.java:121)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
web.xml
<filter>
<filter-name>requestLogFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>requestLogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
根上下文.xml
<bean id="inboundRequestLogStore" class="com.my.project.services.log.InboundRequestLogStore" />
<bean id="requestLogFilter" class="com.my.project.config.filter.RequestLogFilter" />
组件(用bean的id标记)
Components (marked with bean's id)
@Component("inboundRequestLogStore")
public class InboundRequestLogStore implements InitializingBean {
-
@Component("requestLogFilter")
public class RequestLogFilter implements Filter {
@Configurable 在 RequestLogFilter 上不起作用.
@Configurable on the RequestLogFilter not working.
结果
ikettu,谢谢!
经过一些尝试,我实现了不能为空的自动装配字段.我已经将 bean 添加到 root-context.xml
after some attempts I've achieved autowired fields not to be nullable. I've added beans to the root-context.xml
<bean id="requestLogFilter" class="com.my.project.config.filter.RequestLogFilter">
<constructor-arg ref="inboundRequestLogStore"/>
</bean>
<bean id="inboundRequestLogStore" class="com.my.project.service.InboundRequestLogStore">
<constructor-arg ref="logService"/>
</bean>
<bean id="logService" class="com.my.project.service.LogService">
<constructor-arg ref="entityManagerFactory"/>
</bean>
在类中,我用这样的参数创建了构造函数
In classes I've created constructors with params like this
private LogServic logService;
public InboundRequestLogStore(LogServic logService) {
this.logService = logService;
} ....
在日志服务中
private EntityManagerFactory emf;
public void setEntityManagerFactory(EntityManagerFactory emf) {
this.emf = emf;
}
但是当我尝试将我的实体保存到数据库时什么也没发生.如果我尝试刷新一批插入并释放内存
But when I tried to save my entity to DB nothing has happened. If I tried to flush a batch of inserts and release memory
entityManager.flush();
entityManager.clear();
然后 NotOpenedTransaction(像这样,我想不起来了)异常发生了
then NotOpenedTransaction(like this, I can't call to mind) exception has occured
我厌倦了所有并创建了一个拦截器.一切都完美无缺.如果有人可以解释过滤器的问题,请发表评论.
I'm tired of all and have created an interceptor. And all works perfetcly. If anyone can explain what was the problem with the filter please comment.
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- <filter> -->
<!-- <filter-name>requestLogFilter</filter-name> -->
<!-- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> -->
<!-- if set this parameter to true then filter init & destroy methods will be called -->
<!-- <init-param> -->
<!-- <param-name>targetFilterLifecycle</param-name> -->
<!-- <param-value>true</param-value> -->
<!-- </init-param> -->
<!-- </filter> -->
<!-- <filter-mapping> -->
<!-- <filter-name>requestLogFilter</filter-name> -->
<!-- <url-pattern>/*</url-pattern> -->
<!-- </filter-mapping> -->
</web-app>
推荐答案
很可能您现在将 servlet 过滤器初始化为普通的 java 类,而不是初始化的 bean.
Most probably you now initialize servlet filter as normal java class and not as initialized bean.
请使用 DelegatingFilterProxy将春豆用作 serlvet 过滤器
Please use DelegatingFilterProxy to have spring beans as serlvet filters
检查文章 https://dzone.com/articles/what-does-spring-delegatingfilterproxy-do
这篇关于自动装配空指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!