這一章節主要介紹SpringBoot的使用,也是學習的重點內容,之後就打算用SpringBoot來寫後臺,所以提前看一下還是很有必要的。
3.SpringBoot概況
3.1.1SpringBoot發展背景
Spring Boot的出現。Spring Boot可讓開發人員不再需要編寫複雜的XML配置檔案,僅通過幾行程式碼就能實現一個可執行的Web應用。
Spring Boot革新Spring專案開發體驗之道,其實是藉助強大的Groovy 動態語言實現的,如藉助Groovy強大的 MetaObject協議、可插拔的AST轉換器及內建的依賴解決方案引擎等。在其核心的編譯模型中,Spring Boot使用Groovy來構建工程檔案,所以它可以輕鬆地利用匯入模板及方法模板對類所生成的位元組碼進行改造,從而讓開發者僅很簡潔的程式碼就可以完成很複雜的操作。
從Spring Boot專案名稱中的 Boot可以看出,Spring Boot的作用在於建立和啟動新的基於Spring框架的專案,其目的是幫助開發人員快速構建出基於Spring 的應用。SpringBoot像一個“管家”,它會在後臺“智慧地”整合專案所需的第三方依賴類庫或框架,因此大部分基於Spring Boot的應用僅需要很少的配置就可以執行起來。
Spring Boot包含如下特性:
為開發者提供Spring 快速入門體驗
內嵌Tomcat和 Jetty容器,不需要部署WAR檔案到Web容器就可獨立執行應用。
提供許多基於Maven的pom配置模板來簡化工程配置。提供實現自動化配置的基礎設施。
提供可以直接在生產環境中使用的功能,如效能指標。
應用資訊和應用健康檢查開箱即用,沒有程式碼生成,也無須XML配置檔案,支援修改預設值來滿足特定需求。
3.2快速配置。
我們以Maven方式快速建立一個 Spring Web應用,首先需要在pom.xml檔案中引入 Spring Boot依賴。引用了一個spring-boot-starter-web啟動器依賴,不像在第2章中的示例一樣,需要引入很多Spring子模組依賴。其他的模組都已經封裝好了。
@EnableAutoConfiguration註解是由Boot提供的,用於對Spring框架進行自動配置,減少了開發人員的工作量;@RestController和@RequestMapping註解是由SpringMVC提供的,用於建立Rest 服務。
雖然Spring Boot沒有強制要求工程程式碼結構按某種方式進行組織,但為了編寫程式碼的可讀性,建議採用所示的包組織方式。
建議將應用的主類放在主包外層,將Application應用主類放在com.smart主包下。這個主類宣告瞭main()方法,並在類級別上標註@Configuration、@ComponentScan,@EnableAutoConfiguration注解。在Spring Boot 1.2+中可以使用@SpringBootApplication註解代替上面3個註解。其他子包規劃包括Web、Service、Domain、DAO等。一個典型的Application主類如程式碼所示。
3.4持久層
Spring框架提供了幾種可選的運算元據庫方式,可以直接使用Spring 內建輕量級的JdbcTemplate,也可以使用第三方持久化框架Hibernate或 MyBaits。Spring Boot為這兩種運算元據庫方式分別提供了相應的啟動器spring-boot-starter-jdbc和 spring-boot-starter-jpa。應用Spring Boot啟動器使資料庫持久化操作變得更加簡單,因為Spring Boot會自動配置訪問資料庫相關設施。只需在工程模組 pom.xml檔案中新增spring-boot-starter-data-jdbc或spring-boot-starter-data-jpa依賴即可。下面將採用Boot 提供的JDBC啟動器來實現第⒉章登入示例的持久層。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.3.RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>chapter3</artifactId> <name>Spring4.x第三章例項</name> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> ...
匯入依賴包之後,為了讓Spring Boot能夠自動裝配資料來源的連線,需要在資源根目錄resources下建立一個application.properties,配置資料庫的連線資訊,如程式碼所示。
在Spring Boot 中,可以通過兩種方式配置資料庫連線。一種是通過自定義連線的方式,如在配置檔案①-1處,通過配置spring.datasource.*選項設定資料來源的連結地址、連線驅動器、使用者名稱及密碼。在預設情況下,Boot啟動器自動建立tomcat-jdbc連線池。如果不想採用預設的連線池,則可以通過 spring.datasource.type屬性手工指定專案所需的連線池(如DBCP、C3PO)。
另外一種是通過JNDI方式設定,在生產環境中通常會採用此種方式。如在示例②處,為spring.datasource.jndi-name屬性指定一個JNDI連線名稱即可。
在 Boot中提供了靈活的資料庫初始化方式,可以設定DDL指令碼,也可以設定DML指令碼。如示例③處,spring.datasource.initialize 屬性設定啟動的時候是否進行初始化;spring.datasource.platform 屬性設定當前資料庫型別(如Oracle、MySQL、SQL Server等); spring.datasource.data屬性設定DML 指令碼檔名稱,在啟動的時候會從類根路徑載入data-S{platform}.sql檔案執行,其中$ {platform}為當前資料庫型別,本示例配置會載入data-mysql.sql; spring.datasource.schema屬性設定DDL指令碼檔名稱,在啟動的時候會從類根路徑載入schema-mysql.sql檔案執行。
3.4.2UserDao
這裡用@Repository定義了一個DAO Bean,用@Autowired將Spring容器中的 Bean注入進來。這個寫法與第⒉章中的示例一致。細心的讀者可能會有疑問:採用Boot方式與普通的方式不是一樣的嗎?
大家可以回顧一下第2章的持久層,寫完了業務操作DAO之後,還有一個重要的步驟,就是要在Spring容器中裝配DAO。
在Spring Boot中,這個步驟就不需要了,Boot 會自動幫我們裝配好。這就是SpringBoot的強大之處,開發人員只需關注業務的實現,而無須關注Bean裝配等配置,這也是Spring Boot設計的初衷。
3.5業務層
在編寫業務層程式碼時有兩個重要的步驟:一是編寫正確的業務邏輯;二是對業務事務的管控。在 Spring Boot中,使用事務非常簡單,首先在主類Application 上標註@EnableTransactionManagement註解(開啟事務支援,相當於XML中的<tx:annotation-driven/>配置方式),然後在訪問Service方法上標註@Transactional註解即可。如果將@Transactional註解標註在Service類級別上,那麼當前Service類的所有方法都將被事務增強,建議不要在類級別上標註@Transactional註解。
通過@EnableTransactionManagement註解,Boot為應用自動裝配了事務支援。這對使用者並不透明,使用者如果想自己定義事務管理器,則在Application類中新增一個即可,如程式碼所示。
在Application中新增自定義事務管理器方法txManager),並在方法上標註@Bean註解,此時Spring Boot 會載入自定義的事務管理器,不會重新例項化其他事務管理器。
如果在實際的專案中需要分散式事務支援,那麼,Boot也提供了很好的支援,它整合了Atomikos和 Bitronix分散式事務處理框架,可以根據需要匯入相應的啟動器( spring-boot-starter-jta-atomikos或spring-boot-starter-jta-bitronix)。
3.6展現層
3.6.1配置pom.xml依賴
由於在示例中使用JSP作為檢視,且用到了JSTL標籤,因此需要再新增相關的依賴包,如程式碼所示。
<dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency>
3.6.2配置Spring MVC框架
在 Boot環境中配置MVC很簡單,只要將上面的應用啟動類Application稍作修改即可,如程式碼所示。
在①處繼承了Spring Boot提供的Servlet初始化器SpringBootServletInitializer,在②處重寫了SpringBootServletInitializer 的configure()方法。
3.6.3處理登入請求
首先需要編寫的是LoginController,它負責處理登入請求,完成登入業務,並根據登入成功與否轉向歡迎頁面或失敗頁面。這與第2章示例LoginController一致,如程式碼所示。
@RestController public class LoginController{ private UserService userService; @RequestMapping(value = {"/","/index.html"}) public ModelAndView loginPage(){ return new ModelAndView("login"); } @RequestMapping(value = "/loginCheck.html") public ModelAndView loginCheck(HttpServletRequest request,LoginCommand loginCommand){ boolean isValidUser = userService.hasMatchUser(loginCommand.getUserName(), loginCommand.getPassword()); if (!isValidUser) { return new ModelAndView("login", "error", "使用者名稱或密碼錯誤。"); } else { User user = userService.findUserByUserName(loginCommand .getUserName()); user.setLastIp(request.getLocalAddr()); user.setLastVisit(new Date()); userService.loginSuccess(user); request.getSession().setAttribute("user", user); return new ModelAndView("main"); } } @Autowired public void setUserService(UserService userService) { this.userService = userService; } }
編寫好登入控制器LoginController 之後,接下來配置MVC檢視對映。首先建立一個資料夾用於存放JSP檔案。為了統一規範,在 src/main/webapp/WEB-INF目錄下建立一個jsp資料夾,並將第﹖章示例中建立的兩個頁面(login.jsp 或main.jsp〉複製到此目錄。
在預設情況下,Spring Boot對/static、/public、/resources或/META-INF/ resources目錄下的靜態檔案提供支援,所以我們可以將應用中的靜態檔案(JS、CSS、Image等)放到這幾個目錄中。
規劃好檢視目錄後,最後一步就是在 application.properties 中配置建立好的檢視的路徑。
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
通過spring.mvc.view.prefix 屬性指定檢視路徑的字首,通過 spring.mvc.view.suffix屬性指定檢視檔案的字尾。至此,我們就完成了對第⒉章登入示例的改造工作。
最後,通過Spring Boot執行應用外掛。雙擊spring-boot:run命令,即可啟動應用。
基於Spring Boot應用,由於當前應用包含了一個可直接執行的Application類,所以在開發過程中,大家很容易在IDE(如 IDEA 工具)中單擊滑鼠右鍵執行當前類。雖然可以啟動當前應用,在非 Web應用中可能不會有什麼問題,但在 Web 應用中,如果採用上述方法直接執行應用,那麼在訪問有檢視的頁面時(如JSP),會一直報404錯誤。
因為直接執行當前啟動類,Spring Boot無法找到當前頁面資源。因此,基於SpringBoot 的應用在開發除錯的時候,一定要基於Spring Boot提供的 spring-boot-maven-plugin外掛命令來執行應用或通過Spring Boot命令列來執行應用。
基於Spring Boot應用,新增監控功能非常簡單,只需在應用的pom.xml檔案中新增spring-boot-starter-actuator依賴即可。