不使用任何知名MVC框架,仅用Servlet+jsp完成View层的开发。基于接口开发测试,要集成Spring+Hibernate,遇到Spring Bean注入Servlet的问题。
在applicationContext.xml中定义数据层访问Bean:
<bean id="userDao" class="test.UserDaoImpl"></bean>
UserDaoImpl是一个使用Hibernate访问数据库的类,包括了一些简单增删改查的方法,如getAll(),save()等
MyServlet.java代码如下:
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public MyServlet() {
super();
}
public void init(ServletConfig config) throws ServletException {
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
List<User> list = userDao.getAll();
out.println("<html>");
out.println("<body>");
out.println("<pre>ID\tNAME");
for (User u : list) {
out.println(u.getUserId() + "\t" + u.getUserName());
}
out.println("</pre>");
out.println("</body>");
out.println("</html>");
out.close();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
}
}
很显然,如果不加处理,下面这一行一定会抛出java.lang.NullPointerException。
List<User> list = userDao.getAll();
解决方法一:
在Servlet的init方法中增加以下代码,即可通知Servlet在启动时,自动查找userDao Bean并装配。
public void init(ServletConfig config) throws ServletException {
ServletContext servletContext = config.getServletContext();
WebApplicationContext webApplicationContext = WebApplicationContextUtils
.getWebApplicationContext(servletContext);
AutowireCapableBeanFactory autowireCapableBeanFactory = webApplicationContext
.getAutowireCapableBeanFactory();
autowireCapableBeanFactory.configureBean(this, "userDao");
}
可是下面这一行需要将Bean Name硬编码到java源码中,让我很不爽。
autowireCapableBeanFactory.configureBean(this, "userDao");
解决办法二(推荐):
还是在Servlet的init方法中增加以下代码。
public void init(ServletConfig config) throws ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
config.getServletContext());
}
并且在变量userDao上一行增加@Autowired
@Autowired
private UserDao userDao;
这样,就不用硬编码Bean Name到java源码中了。