Spring中,web应用启动的顺序是:listener->filter->servlet.
先初始化listener,然后再来就filter的初始化,再接着才到我们的dispathServlet的初始化,
因此,当我们需要在filter里注入一个注解的bean时,就会注入失败,
因为filter初始化时,注解的bean还没初始化,没法注入。
解决方案:
在init方法中注入
主要代码如下
package com.api.config; import java.io.IOException; import java.util.Date; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.http.MediaType; import org.springframework.util.StringUtils; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.ContentCachingResponseWrapper; import com.api.constant.App; import com.api.constant.DataStatus; import com.api.sequence.LogSequence; import com.common.util.DateUtil; import com.domain.UserAdCreateLog; import com.service.UserAdCreateLogService; public class HttpStreamFilter implements Filter { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private static final String REQUEST_ID = "requestId"; @Autowired private UserAdCreateLogService userAdCreateLogService; @Override public void init(FilterConfig filterConfig) throws ServletException { ServletContext context = filterConfig.getServletContext(); ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); userAdCreateLogService = ctx.getBean(UserAdCreateLogService.class); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String requestId = LogSequence.get(); MDC.put(REQUEST_ID, requestId); HttpServletRequest req = (HttpServletRequest) request; String contentType = request.getContentType(); HttpServletResponse res = (HttpServletResponse) response; logger.info("request url : {}",req.getRequestURL().toString()); logger.info("request method : {}",req.getMethod()); logger.info("request ip : {}",request.getRemoteAddr()); if ((contentType != null) && (contentType.indexOf(MediaType.MULTIPART_FORM_DATA_VALUE) != -1)) { chain.doFilter(request, response); } else { ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(req); ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(res); try { chain.doFilter(requestWrapper, responseWrapper); } finally { if (StringUtils.hasLength(req.getQueryString())){ logger.info("query String parameters : {}", req.getQueryString()); } if (requestWrapper.getContentAsByteArray().length > 0) { logger.info("request payload: {}", new String(requestWrapper.getContentAsByteArray())); } String responseBody = new String(responseWrapper.getContentAsByteArray()); logger.info("http response status {}", res.getStatus()); logger.info("response : {}", responseBody); if (req.getRequestURI() != null && App.USER_AD_CREATE_URIS.contains(req.getRequestURI())){ UserAdCreateLog userAdCreateLog = new UserAdCreateLog(); Date datetime = DateUtil.getServerTime(); userAdCreateLog.setRequestId(MDC.get(REQUEST_ID)); userAdCreateLog.setUrl(req.getRequestURI()); if (StringUtils.hasLength(req.getQueryString())){ userAdCreateLog.setRequest(req.getQueryString()); } if (requestWrapper.getContentAsByteArray().length > 0) { userAdCreateLog.setRequest(new String(requestWrapper.getContentAsByteArray())); } userAdCreateLog.setResponse(responseBody); userAdCreateLog.setStatus(DataStatus.Y.getCode()); userAdCreateLog.setModifyTime(datetime); userAdCreateLog.setCreateTime(datetime); userAdCreateLogService.create(userAdCreateLog); } responseWrapper.copyBodyToResponse(); } } MDC.remove(REQUEST_ID); } @Override public void destroy() { } }