为什么在这个春季的应用程序中,自动装配的bean在过滤器中为空? [英] why is autowired bean null in filter in this spring application?

查看:251
本文介绍了为什么在这个春季的应用程序中,自动装配的bean在过滤器中为空?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我简化了生产应用程序以重现错误.

I have simplified our production application to reproduce the errors.

这是一个演示应用程序,用于计算传入请求的数量.

This is a demo application to calculate the counts of incoming requests.

当我调试项目时,我看到Null Pointer Exception被抛出 CounterMetricsFilter类中的manager.incrementRequestCounter(url)行如下所示.那是因为我拥有autowired的经理是NULL.

when I debugged the project, I can see Null Pointer Exception being thrown at manager.incrementRequestCounter(url) line in CounterMetricsFilter class shown below. That is because manager I have autowired is NULL.

但是,CounterController中的同一管理器autowired不为空.我通过调试器确认了这一点.

However, the same manager autowired in CounterController is NOT null. I confirmed this through debugger.

这是怎么了? filters不能是beans吗?如何在不使用Spring MVC应用程序中使用web.xml的情况下实现此功能.

what is wrong here? can filters not be beans? how can I get to this to work without using web.xml in Spring MVC application.

谢谢

Controller

@Controller
@RequestMapping("/counter")
public class CounterController {

@Autowired
CounterManager manager;

 @RequestMapping(value = "/counterMetrics", method = RequestMethod.GET)
    @ResponseBody
    public Map getFeatureStatus(final HttpServletResponse response) {
        System.out.println("returning feautre status");
        return manager.getQueryCounts();
    }
}

Manager

@Service
public class CounterManager {

private Map<String,Integer> queryCounts =
            new ConcurrentHashMap<String,Integer>(1000);

int threshold;
long timestamp;

 @Autowired
  public CounterManager(@Value("${healthThreshold: 10}")
                                 int threshold) {
      this.threshold = threshold * MEGABYTES;
      this.timestamp = System.currentTimeMillis();
  }


 public void incrementRequestCounter(String urlPath){
     Integer oldVal, newVal;
     do {
       oldVal = queryCounts.get(model);
       newVal = (oldVal == null) ? 1 : (oldVal + 1);
     } while (!queryCounts.replace(model, oldVal, newVal));
 }

public Map<StatusUrlModel, Integer> getQueryCounts() {
    return queryCounts;
}

}

Filter

@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class CounterMetricsFilter extends OncePerRequestFilter {

    @Autowired
    CounterManager manager;

    public CounterMetricsFilter(){

    }


    @Override
    protected void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain chain) throws ServletException,
            IOException {
        String path = new UrlPathHelper().getPathWithinApplication(request);
        try {
            chain.doFilter(request, response);
        }
        finally {
            recordMetrics(request, path);
        }
    }

   private void recordMetrics(String path) {
        try {
        manager.incrementRequestCounter(url);
        }
        catch (Exception ex){
            System.out.println("exception is thrown " + ex.getCause());
            ex.printStackTrace();
        }
    }
}

更新:

在控制台上打印以下内容:

The get the following printed on console:

exception is thrown null(来自上面的CounterMetricsFilter). stackTrace:

exception is thrown null (coming from CounterMetricsFilter above). stackTrace:

java.lang.NullPointerException
    at com.myapp.filter.CounterMetricsFilter.recordMetrics(CounterMetricsFilter.java:81)
    at com.myapp.filter.CounterMetricsFilter.doFilterInternal(CounterMetricsFilter.java:63)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.myapp.filter.RequestWrapperFilter.doFilter(RequestWrapperFilter.java:24)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.myapp.filter.GCCORSFilter.doFilter(GCCORSFilter.java:37)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

推荐答案

Servlet容器实例化了一个过滤器,因此@Autowired没有用.

A filter is instantiated by the servlet container so @Autowired is useless.

您可以使用DelegatingFilterProxy让Spring实例化过滤器:

You can use a DelegatingFilterProxy to let Spring instantiate the filter:

<filter>
  <filter-name>counterMetricsFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

这篇关于为什么在这个春季的应用程序中,自动装配的bean在过滤器中为空?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆