先把代码贴上去,后面再复述原理。
一般,我们是在web.xml里面配置springMVC的入口类,DispatcherServlet。因为一切http请求都从DispatcherServlet过。
这里,我们自定义一个类EntryServlet,继承DispatcherServlet。并在web.xml里面配置这个类,实现doDispatch(final HttpServletRequest request, final HttpServletResponse response)方法。
这样,每个http请求都会从自定义类EntryServlet的doDispatch()过。
web.xml:
<!-- Spring Servlet入口 -->
<servlet>
<servlet-name>entry</servlet-name>
<servlet-class>com.xx.EntryServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--过滤一切http请求-->
<servlet-mapping>
<servlet-name>entry</servlet-name>
<url-pattern>*</url-pattern>
</servlet-mapping>
自定义类EntryServlet:
public class EntryServlet extends DispatcherServlet {
private TransactionTemplate tt;//事务管理模板类
@Override
public void init(ServletConfig config) throws ServletException {
final ApplicationContext appContext = SpringContextUtils.getInstance().getContext(getServletContext());
tt = (TransactionTemplate) appContext.getBean("txTemplate");
}
public void doDispatch(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
if ("1".equals(request.getParameter("nodb"))) {
superDoDispatch(request, response);
} else {
try {
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
superDoDispatch(request, response);
} catch (Exception e) {
status.setRollbackOnly();
throw new MyException(e);
}
}
});
} catch (MyException e) {
throw e.getInner();
}
}
}