Java EE servlet作为spring bean代理

问题描述:

我有一个名为com.sample.servlets.CreateReleaseServlet的servlet,我试图在辅助方法中添加spring AOP通知。Java EE servlet作为spring bean代理

我在Spring配置文件中的以下代码:

<bean id="customerService" class="com.sample.servlets.CreateReleaseServlet"> 
</bean> 

<bean id="notificationAdvice" class="com.sample.advice.NotificationAdvice" /> 

<bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> 

    <property name="target" ref="customerService" /> 

    <property name="interceptorNames"> 
     <list> 
      <value>notificationAdvice</value> 
     </list> 
    </property> 
</bean> 

当我尝试使用下面的Java代码来获得这个servlet豆:

ApplicationContext appContext = new ClassPathXmlApplicationContext(
     new String[] { "/WEB-INF/form-servlet.xml" }); 
CreateReleaseServlet servlet = (CreateReleaseServlet) appContext.getBean("customerServiceProxy"); 

String next = servlet.execute(req); 

我得到以下异常:

com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[CreateReleaseServlet]: java.lang.ClassCastException: $Proxy103 incompatible with com.sample.servlets.CreateReleaseServlet 
     at com.sample.servlets.CreateReleaseServlet.service(CreateReleaseServlet.java:1823) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:668) 
     at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1229) 
     at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:774) 
     at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:456) 
     at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178) 
     at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:136) 
     at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:97) 
     at com.sample.servlets.SampleFilter.doFilter(Unknown Source) 
     at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:195) 
     at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91) 
     at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:928) 
     at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1025) 
     at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3751) 
     at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:304) 
     at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:962) 
     at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1662) 
     at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:195) 
     at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:452) 
     at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:511) 
     at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:305) 
     at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83) 
     at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165) 
     at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217) 
     at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161) 
     at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138) 
     at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204) 
     at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775) 
     at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905) 
     at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1690) 

任何建议将会很有帮助

除非您启用了类的代理(而不是接口的普通JdkProxy),否则这将不起作用,因为代理对象不会充当您的servlet的子类。您可以将其转换为Servlet的实例。也就是说,你的方法看起来有点奇怪。你的拦截器是做什么的?使用servlet执行AOP(ish)东西的常见方式是创建一个servlet过滤器。如果这不是一个选项,我建议你将你的servlet转换为Spring MVC控制器,并使用常规的Spring MVC选项来配置拦截器。

+0

我不知道该如何谢谢。你救了我很多麻烦。目前,我所做的是:1)用我从servlet的服务方法调用的方法创建一个接口(在我的例子中是执行方法)2)使servlet实现这个接口3)将getBean调用修改为与新界面一起工作。 4)在界面上调用执行方法。如果没有你的答复,这又是不可能的。我读过可以通过使用CGLib避免接口.http://insufficientinformation.blogspot.in/2007/12/spring-dynamic-proxies-vs-cglib-proxies.html – Sandeep 2013-04-04 08:26:45

+0

太棒了! :)但是我会考虑最终将其重构为servlet过滤器或Spring MVC控制器。 – NilsH 2013-04-04 09:14:24