我想利用 Sotirios Delimanolis 提供的解决方案,但添加透明的自动装配。
这个想法是将普通的 servlet 转变为自动装配感知对象。
因此,我创建了一个父抽象 servlet 类,它检索 Spring 上下文、获取具有自动装配功能的工厂,并使用该工厂自动装配 servlet 实例(实际上是子类)。我还将工厂存储为实例变量,以防子类需要它。
所以父抽象 servlet 看起来像这样:
public abstract class AbstractServlet extends HttpServlet {
protected AutowireCapableBeanFactory ctx;
@Override
public void init() throws ServletException {
super.init();
ctx = ((ApplicationContext) getServletContext().getAttribute(
"applicationContext")).getAutowireCapableBeanFactory();
//The following line does the magic
ctx.autowireBean(this);
}
}
sevlet 子类如下所示:
public class EchoServlet extends AbstractServlet {
@Autowired
private MyService service;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.getWriter().println("Hello! "+ service.getMyParam());
}
}
请注意,EchoServlet 唯一需要做的就是在常见的 Spring 实践中声明一个 bean。魔法是在超类的 init() 方法中完成的。
我还没有彻底测试过。但它与一个简单的 bean MyService 一起使用,该 bean 还从 Spring 管理的属性文件中自动装配属性。
Enjoy!
Note:
最好使用 Spring 自己的上下文侦听器加载应用程序上下文,如下所示:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
然后像这样检索它:
WebApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(getServletContext());
ctx = context.getAutowireCapableBeanFactory();
ctx.autowireBean(this);
只需要导入spring-web库,不需要导入spring-mvc。