Servlet不能通过Spring依赖注入
2017-11-11 00:00
357 查看
摘要: Servlet不能通过Spring依赖注入
在今天这个特殊的日子里(双十一)要在自己的项目中对外暴露一个接口,供其他程序进行访问,使用的是一个统一的Servlet对外来暴露接口,但是出现了一个很棘手的问题,那就是在Tomcat服务起来之后,在浏览器进行访问的时候,报一个500的错误!让我真的很费解,错误如下:
HTTP Status 500 - Error instantiating servlet class com.hr.rmi.RemoteServiceServlet
type Exception report
message Error instantiating servlet class com.hr.rmi.RemoteServiceServlet
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException:Errorinstantiatingservlet class com.yinker.hr.rmi.RemoteServiceServlet org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) java.util.concurrent.ThreadPoolExecutor.runWorker(UnknownSource) java.util.concurrent.ThreadPoolExecutor$Worker.run(UnknownSource) java.lang.Thread.run(UnknownSource)root causejavax.naming.NamingException:Cannotcreateresourceinstance org.apache.naming.factory.ResourceEnvFactory.getObjectInstance(ResourceEnvFactory.java:117) javax.naming.spi.NamingManager.getObjectInstance(UnknownSource) org.apache.naming.NamingContext.lookup(NamingContext.java:843) org.apache.naming.NamingContext.lookup(NamingContext.java:168) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) java.util.concurrent.ThreadPoolExecutor.runWorker(UnknownSource) java.util.concurrent.ThreadPoolExecutor$Worker.run(UnknownSource) java.lang.Thread.run(Unknown Source)
然后开始上网进行疯狂的查找,找了半天,很多都是说web.xml中servlet-class配置的不对,没有含有包名,或者是包名错误导致的,但是我的包名确实是正确的。
但是在最后我发现了我的代码中引用的一个service相比于其他代码,是采用Spring依赖注入的方式注入的,代码如下:
@Resource(name="testservice")
private Testservice testservice;
然后,将这段代码去掉,采用getBean的方式进行的获取,哇,竟然可以了。
替换方式:
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
this.fileResourceService=applicationContext.getBean("testservice", testservice.class);
接着就上网查询这是为啥呢?结果原因如下:
Spring不能通过注解向Servlet中注入实例的原理
想了解此问题的原理,就要了解tomcat启动后 servlet和spring的加载顺讯。
1、 tomcat启动后先加载web.xml文件。web.xml主要配置了servlet 、filter、listenner三种javaee规范的类,加载顺序跟在web.xml文档
中的位置无关。 顺序为 listenner>filter>servlet 。
2、而spring的初始化类为org.springframework.web.context.ContextLoaderListener,就是一个listenner,它是先于servlet加载的。普通servlet和springmvc的入口servlet
的加载顺序,就要看servle的设置了。
3、在 servlet A类上加@service或@controllert等注解时,spring或springmvc会扫面相关包,自动实例化一个servlet 实例A;这个实例A的引用是spring容器管理的。
4、当然 servlet也会在web.xml配置(要不然怎么拦截url),这是tomcat容器会根据servler配置启动时或者第一次请求该url时实例化该servlet 实例B,
这个实例B的引用是tomcat容器管理的。
5、明白了吧,拦截url的servlet和spring依赖注入的servlet不是同一个实例!!所以就产生了不能依赖注入或者注解不起作用的现象。
也就是说Spring管理普通的JavaBean还好,servlet 和filter最后不要使用依赖注入,自己获取最好。
在今天这个特殊的日子里(双十一)要在自己的项目中对外暴露一个接口,供其他程序进行访问,使用的是一个统一的Servlet对外来暴露接口,但是出现了一个很棘手的问题,那就是在Tomcat服务起来之后,在浏览器进行访问的时候,报一个500的错误!让我真的很费解,错误如下:
HTTP Status 500 - Error instantiating servlet class com.hr.rmi.RemoteServiceServlet
type Exception report
message Error instantiating servlet class com.hr.rmi.RemoteServiceServlet
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException:Errorinstantiatingservlet class com.yinker.hr.rmi.RemoteServiceServlet org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) java.util.concurrent.ThreadPoolExecutor.runWorker(UnknownSource) java.util.concurrent.ThreadPoolExecutor$Worker.run(UnknownSource) java.lang.Thread.run(UnknownSource)root causejavax.naming.NamingException:Cannotcreateresourceinstance org.apache.naming.factory.ResourceEnvFactory.getObjectInstance(ResourceEnvFactory.java:117) javax.naming.spi.NamingManager.getObjectInstance(UnknownSource) org.apache.naming.NamingContext.lookup(NamingContext.java:843) org.apache.naming.NamingContext.lookup(NamingContext.java:168) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) java.util.concurrent.ThreadPoolExecutor.runWorker(UnknownSource) java.util.concurrent.ThreadPoolExecutor$Worker.run(UnknownSource) java.lang.Thread.run(Unknown Source)
然后开始上网进行疯狂的查找,找了半天,很多都是说web.xml中servlet-class配置的不对,没有含有包名,或者是包名错误导致的,但是我的包名确实是正确的。
但是在最后我发现了我的代码中引用的一个service相比于其他代码,是采用Spring依赖注入的方式注入的,代码如下:
@Resource(name="testservice")
private Testservice testservice;
然后,将这段代码去掉,采用getBean的方式进行的获取,哇,竟然可以了。
替换方式:
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
this.fileResourceService=applicationContext.getBean("testservice", testservice.class);
接着就上网查询这是为啥呢?结果原因如下:
Spring不能通过注解向Servlet中注入实例的原理
想了解此问题的原理,就要了解tomcat启动后 servlet和spring的加载顺讯。
1、 tomcat启动后先加载web.xml文件。web.xml主要配置了servlet 、filter、listenner三种javaee规范的类,加载顺序跟在web.xml文档
中的位置无关。 顺序为 listenner>filter>servlet 。
2、而spring的初始化类为org.springframework.web.context.ContextLoaderListener,就是一个listenner,它是先于servlet加载的。普通servlet和springmvc的入口servlet
的加载顺序,就要看servle的设置了。
3、在 servlet A类上加@service或@controllert等注解时,spring或springmvc会扫面相关包,自动实例化一个servlet 实例A;这个实例A的引用是spring容器管理的。
4、当然 servlet也会在web.xml配置(要不然怎么拦截url),这是tomcat容器会根据servler配置启动时或者第一次请求该url时实例化该servlet 实例B,
这个实例B的引用是tomcat容器管理的。
5、明白了吧,拦截url的servlet和spring依赖注入的servlet不是同一个实例!!所以就产生了不能依赖注入或者注解不起作用的现象。
也就是说Spring管理普通的JavaBean还好,servlet 和filter最后不要使用依赖注入,自己获取最好。
相关文章推荐
- Spring不能通过注解向Servlet中注入实例的原理和解决办法
- 通过spring在filter注入bean(DelegatingFilterProxy与servlet filter) .
- spring+mybatis监听contral类后不能依赖注入解决
- 在Servlet中可访问Spring bean对象,但是不能直接以注入的方式引用
- Spring quartz Job不能依赖注入,Spring整合quartz Job任务不能注入
- spring通过注解依赖注入和获取xml配置混合的方式
- 通过代理的方式让Spring注入Servlet
- session监听器中不能使用spring依赖注入
- @resource或@Autowired Service service不能通过spring注入问题
- 一个和spring整合的依赖注入的servlet,子类可自动装配依赖Bean
- 原始方式:spring四种依赖注入方式 |注解方式:Spring零配置通过注解实现Bean依赖注入
- Spring 通过【构造函数】注入依赖
- Spring架构学习(2)通过Properties文件实现依赖注入
- Spring通过构造方法依赖注入
- Spring零配置通过注解实现Bean依赖注入总结<转>
- Spring依赖注入servlet会话监听器
- 利用抽象工厂创建DAO、利用依赖注入去除客户端对工厂的直接依赖、将有关Article的各种Servlet封装到一个Servlet中(通过BaseServlet进行
- 通过spring在filter注入bean(DelegatingFilterProxy与servlet filter)
- 一个和spring整合的依赖注入的servlet,子类可自动装配依赖Bean