[SPRING] Autowired Null 포인터 예외
SPRINGAutowired Null 포인터 예외
DB에 요청을 저장하는 필터가 있습니다. 하지만 autowired 필드 인 NullPointerException : inboundRequestLogStore가 발생합니다.
필자는 Filter Bean 클래스에서 Bean을 사용하여 제안을 시도 했습니까? (SpringBeanAutowiringSupport.processInjectionBasedOnServletContext (this, filterConfig.getServletContext ());를 필터 init 메소드에 추가하고 내 root-context.xml에 bean을 정의하고 이제는 RequestLogFilter 클래스에서 작동합니다. 하지만, InboundRequestLogStore 클래스에서 필자는 다른 엔터티를 DB에 저장하기 위해 autowired 된 logService를 가지고 있습니다. 그리고 지금이 시점에서 NullPointerEception을 얻습니다. 왜 NPE를 사용하고 어떻게 해결해야합니까? 내 프로젝트의 다른 부분에 동일한 서비스 / 구성 요소가 있으며 문제없이 서비스를 제공합니다. 필터 만 사용하는 데 문제가 있습니다.
@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);
}
}
}
}
StackTrace
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를 사용하면 얻을 수 있습니다.
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)
을 포함한다.
<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>
root-context.xml
<bean id="inboundRequestLogStore" class="com.my.project.services.log.InboundRequestLogStore" />
<bean id="requestLogFilter" class="com.my.project.config.filter.RequestLogFilter" />
구성 요소 (bean의 id로 표시)
@Component("inboundRequestLogStore")
public class InboundRequestLogStore implements InitializingBean {
-
@Component("requestLogFilter")
public class RequestLogFilter implements Filter {
RequestLogFilter에서 @Configurable이 작동하지 않습니다.
그 결과
이케트, 고마워!
몇몇 시도 후에 autowired 필드를 nullable로 만들지 못했습니다. 나는 root-context.xml에 bean을 추가했다.
<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>
클래스에서는이 같은 params 가진 생성자를 만들었습니다.
private LogServic logService;
public InboundRequestLogStore(LogServic logService) {
this.logService = logService;
} ....
LogService에서
private EntityManagerFactory emf;
public void setEntityManagerFactory(EntityManagerFactory emf) {
this.emf = emf;
}
그러나 DB에 내 엔티티를 저장하려고 할 때 아무 일도 일어나지 않았습니다. 일괄 삽입을 플러시하고 메모리를 해제하려고하면
entityManager.flush();
entityManager.clear();
그 다음 열지 않은 트랜잭션 (이와 같이, 나는 마음에 부를 수 없다) 예외가 발생했다.
나는 모든 것에 지쳤으며 요격기를 만들었습니다. 그리고 모든 것이 완벽하게 작동합니다. 누구든지 필터의 문제점을 설명 할 수 있다면 의견을 말하십시오.
웹
<?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>
해결법
-
==============================
1.대부분의 경우 서블릿 필터를 초기화 된 bean이 아닌 일반 Java 클래스로 초기화합니다.
대부분의 경우 서블릿 필터를 초기화 된 bean이 아닌 일반 Java 클래스로 초기화합니다.
DelegatingFilterProxy를 사용하십시오. 서블릿 필터로 스프링 빈을 사용하는 방법
문서 https://dzone.com/articles/what-does-spring-delegatingfilterproxy-do를 확인하십시오.
from https://stackoverflow.com/questions/45231663/autowired-null-pointer-exception by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] MessageStore는 Spring Integration + Java Config를 통해 QueueChannel을 지원합니다. (0) | 2019.05.21 |
---|---|
[SPRING] 스프링 보안으로 추가 매개 변수를 확인하십시오. (0) | 2019.05.21 |
[SPRING] Spring Rest 템플릿에서 타임 아웃 설정하기 (0) | 2019.05.21 |
[SPRING] 스프링 3.2.8과 호환되는 스프링 보안 버전 (0) | 2019.05.20 |
[SPRING] JdbcTemplate 형식의 메서드 쿼리 (String, ResultSetExtractor <T>)는 인수 (String, BeanPropertyRowMapper)에 적용 할 수 없습니다. (0) | 2019.05.20 |