由@Resource引出的异常

Posted by 大雁小鱼 on November 6, 2018

平时在开发时遇到一些异常信息,仔细琢磨一下琢磨出点名堂,记录一下,以备以后查阅。

如果你在使用SpringMVC开发程序,在web.xml中可能会编写这样的XML代码:

    <filter>
        <filter-name>loginFilter</filter-name>
        <filter-class>com.xxx.web.filter.LoginFilter</filter-class>
        <init-param>
            <param-name>permitUrls</param-name>
            <param-value>/login,/login/index,/login/submit,/favicon.ico,/login/ajaxNotLogin,/test</param-value>
        </init-param>
    </filter>

LoginFilter类如下

public class LoginFilter extends GenericFilterBean {
  @Resource
  UserService userService;
}

在LoginFilter类中,UserService被加上了@Resource注解,仔细观察这个注解的导入信息

import javax.annotation.Resource;

你会发现这是Java规范里的一个类,而web.xml也是Java规范里定义的一部分,于是在程序启动的时候,Servlet容器会通过命名服务查找是否存在UserService,如果找不到会抛出错误

javax.naming.NamingException: Cannot create resource instance
	at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:96)
	at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
	at org.apache.naming.NamingContext.lookup(NamingContext.java:839)
	at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
	at org.apache.naming.NamingContext.lookup(NamingContext.java:827)
	at org.apache.naming.NamingContext.lookup(NamingContext.java:173)
	at org.apache.catalina.core.DefaultInstanceManager.lookupFieldResource(DefaultInstanceManager.java:589)
	at org.apache.catalina.core.DefaultInstanceManager.processAnnotations(DefaultInstanceManager.java:487)
	at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:174)
	at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:151)
	at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:264)
	at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
	at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4637)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5282)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)

这就是出现这个错误的真正原因,LoginFilter被Servlet容器托管,容器通过命名服务去查找接口实现,而不是按照我们的意愿通过Spring容器去查找Bean!!

但是如果LoginFilter不是由Servlet容器托管的话,就不会出现这个错误了