
Java Tutorial 第四堂(2)使用 spring 相依注入
Java Tutorial 第四堂(1)使用 spring-webmvc 框架 << 前情 在 Java Tutorial 第三堂(2)使用 spring-jdbc 存取資料庫 中看過,為了能夠使用 JDBCDataSource dataSource = new JDBCDataSource(); dataSource.setUrl("jdbc:hsqldb:file:src/main/resources/db/dvd_library"); dataSource.setUser("codedata"); dataSource.setPassword("123456"); 接著 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 然後 DvdDao dvdDao = new DvdDaoJdbcImpl(jdbcTemplate); 物件建立與相依注入物件的建立與相依注入(Dependency Injection)是我們所關心的,只不過當過程太過冗長,模糊了商務流程之時,應該適當地將之分離,也許建立一個工廠方法會比較好: public class DaoHelper { public static DvdDao createDvdDao() { JDBCDataSource dataSource = new JDBCDataSource(); dataSource.setUrl("jdbc:hsqldb:file:src/main/resources/db/dvd_library"); dataSource.setUser("codedata"); dataSource.setPassword("123456"); return new DvdDaoJdbcImpl(new JdbcTemplate(dataSource)); } } 那麼要取得 DvdDao dvdDao = DaoHelper.createDvdDao(); 如此之來,程式碼的流程清晰了,而且即使是不懂 JDBC 或 這個 Spring 相依注入先前的課程中已經使用過 Spring 中的一些方案,實際上,Spring 本身的核心就是一個相依注入容器,而且功能強大,事實上,在 Java Tutorial 第四堂(1)使用 spring-webmvc 框架 中,就已經使用這個功能了,例如,當你在 dispatcher-servlet.xml 中如下設定時: ... <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp"/> ... 因為 spring-webmvc 本身就是基於 Spring 相依注入容器而建立起來的,就是在告知 Spring 為你建立 Spring 的相依注入容器,英文上也常簡稱為 DI(Dependency Injection)容器 ,實際上,更早前 Spring 採用 IoC(Inversion of Control)容器這個名詞,不過這邊的 IoC 與 Java Tutorial 第四堂(1)使用 spring-webmvc 框架 中談到的 IoC 有所不同,Spring 的 IoC 指的是物件建立與相依設定的控制權,由開發者手中轉換至容器身上,而 Web 框架之類的 IoC,指的是對流程的控制權,從開發者手中轉換至框架身上。 簡單來說,Spring 談到的 IoC 容器比較狹義,為了避免名詞混淆,Spring 建立使用 DI 容器來稱呼其核心容器。 練習 12:使用 Spring 相依注入 這個練習要將練習 10 與練習 11 整合在一起,建立一個簡單的 DVD 管理頁面。在 Lab 檔案的 exercises/exercise12 中有個 DVDLibrary 目錄,已經事先將練習 10 與練習 11 中可重用的程式碼(像是 Dvd.java、DvdDao.java 等)與設定檔(像是 web.xml、dispatcher-servlet.xml 等)準備好。 請開啟 DVDLibrary 目錄中的 build.gradle,在其中的 dependencies { runtime 'jstl:jstl:1.2' ... } 這是因為要顯示所有 DVD 清單時,必須得用迴圈之類的語法,不過不建議直接在 JSP 上撰寫 Java 程式碼,JSTL(JavaServer Pages Standard Tag Library)是標準方案,可提供像 HTML 語法的流程標籤,可避免 JSP 頁面中混雜著 Java 程式碼。 接著請開啟 src/main/webapp/WEB-INF 中的 dispatcher-servlet.xml,加入以下設定: <bean class="org.hsqldb.jdbc.JDBCDataSource" p:url="jdbc:hsqldb:file:src/main/resources/db/dvd_library" p:user="codedata" p:password="123456"/> 顯然地,這告訴 Spring 的 DI 容器,要建立 在 src/main/java/tw/codedata 目錄中建立 DvdController.java,內容撰寫如下: package tw.codedata; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; @Controller public class DvdController { private DvdDao DvdDao; @Autowired public void setDvdDao(DvdDao DvdDao) { this.DvdDao = DvdDao; } public DvdDao getDvdDao() { return DvdDao; } @RequestMapping("list") public String list(Model m) { m.addAttribute("dvds", getDvdDao().allDvds()); return "list"; } @RequestMapping("add") public String add( @RequestParam("title") String title, @RequestParam("year") Integer year, @RequestParam("duration") Integer duration, @RequestParam("director") String director, Model m) { Dvd dvd = new Dvd(title, year, duration, director); getDvdDao().saveDvd(dvd); m.addAttribute("dvd", dvd); return "success"; } } 注意到 請在 src/main/webapp 目錄中,建立一個 success.jsp: <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Success</title> </head> <body> You add a DVD. <ul> <li>Title: ${dvd.title}</li> <li>Year: ${dvd.year}</li> <li>Duration: ${dvd.duration}</li> <li>Director: ${dvd.director}</li> </ul> </body> </html> 這個很簡單,再來建立一個 list.jsp: <%@page contentType="text/html" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>All DVDs</title> </head> <body> <c:forEach var="dvd" items="${dvds}"> <h1>${dvd.title}</h1> <ul> <li>Year: ${dvd.year}</li> <li>Duration: ${dvd.duration}</li> <li>Director: ${dvd.director}</li> </ul> <hr> </c:forEach> </body> </html>
DVDLibrary 中還為你建立了 index.jsp、add.jsp,分別是首頁與表單。執行 gradle tomcatRunWar 後,使用瀏覽器連接 http://localhost:8080/DVDLibrary/,就可以進行操作。以下是顯示 DVD 清單的一個頁面示範: |