不使用任何知名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源码中了。