平时在开发时遇到一些异常信息,仔细琢磨一下琢磨出点名堂,记录一下,以备以后查阅。
如果你在使用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容器托管的话,就不会出现这个错误了