在此之前写过一篇文章 一步一步搭建入门Spring Web应用,本篇文章就是在此基础上,运用Spring Boot来简化Spring Web开发。本篇文章中有些类可能会联系到前面一篇文章中出现的类。
Spring Boot诞生的目的就是用来简化Spring应用开发过程。该框架使用了特定的方式来进行配置,从而使得开发人员不在需要定义一系列样板化的配置文件,而专注于核心业务开发。帮助开发人员快速的构建出基于Spring的应用。它会在后台整合项目所需的第三方依赖类库或框架,不再需要编写复杂的XML配置文件,仅通过几行代码就能实现一个可运行的Web应用。
Spring Boot启动器。Spring Boot是由一系列启动器组成的,这些启动器构成一个强大的灵活的开发助手。开发人员根据项目需要,选择并组合相应的启动器,就可以快速搭建一个适合项目需要的基础运行框架。
常用Spring Boot启动器:
创建好Maven项目 IDEA创建Maven工程,然后编辑pom.xml
pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.smartgroupId>
<artifactId>springBootDemo1artifactId>
<packaging>warpackaging>
<version>1.0-SNAPSHOTversion>
<name>springBootDemo1 Maven Webappname>
<url>http://maven.apache.orgurl>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.3.3.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-surefire-pluginartifactId>
<configuration>
<useSystemClassLoader>falseuseSystemClassLoader>
configuration>
plugin>
plugins>
build>
project>
①处继承了Spring Boot提供的根默认配置依赖,这里引入spring-boot-starter-parent的好处是在②处添加启动器时不必再声明版本号。
③处注释掉了一个Jetty容器依赖,Spring Boot默认会采用内嵌的Tomcat运行当前应用,如果想使用Jetty运行当前应用,就加上这个依赖。
④处引用了一个Spring Boot运行插件。刷新IDEA开发工具右边的Maven Projects面板,就可以看到Spring Boot运行命令。
Spring Boot有一个Application应用主类放在com.smart主包下,这个主类声明了main()方法,并在类级别上标注@Configuration、@ComponentScan、@EnableAutoConfiguration注解。在Spring Boot 1.2+中可以使用@SpringBootApplication注解代替前面三个注解。
Application.java
package com.smart;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
/** * Created by Mistra.WR on 2017/8/17/017. */
//@Configuration
//@ComponentScan
//@EnableAutoConfiguration
@SpringBootApplication//此注解可以代替上面三个注解
public class Application{
public static void main(String[] args) throws Exception{
SpringApplication.run(Application.class,args);
}
}
Spring Boot启动应用非常简单,只需在main()方法中通过SpringApplication.run()方法启动即可。
Spring框架提供了几种可选的操作数据库的方式,可以直接使用Spring内置轻量级的JdbcTemplate,也可以使用第三方持久化框架Hibernate或Mybatis。分别提供了相应的启动器spring-boot-starter-jdbc和spring-boot-starter-jpa。
初始化配置,在pom.xml文件中导入spring-boot-starter-jdbc依赖以及访问数据库的JDBC驱动器。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
导入依赖包以后,为了让Spring Boot能够自动装配数据源的连接,需要在资源根目录resources下创建一个application.properties,配置数据库的连接信息。
application.properties
#①配置数据库连接信息
spring.datasource.name=sampleDs
spring.datasource.url=jdbc:mysql://localhost:3306/sampledb
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#②指定自定义连接池
#spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
#③连接池配置信息
spring.datasource.max-wait=10000
spring.datasource.max-active=50
spring.datasource.max-idle=10
spring.datasource.min-idle=8
spring.datasource.test-on-borrow=true
spring.datasource.validation-query=select 1
#④配置JNDI数据源
#spring.datasource.jndi-name=java:comp/env/jdbc/sampleDs
#⑤初始化数据库脚本
#spring.datasource.initialize=true
#spring.datasource.platform=mysql
#spring.datasource.data=data
#spring.datasource.schema=schema
Spring Boot中,可以通过两种方式配置数据库连接。
package com.smart.domain;
import java.io.Serializable;
import java.util.Date;
/** * Created by Mistra.WR on 2017/8/5/005. */
public class User implements Serializable{
private int userID;
private String username;
private String password;
private int credits;
private String lastIp;
private Date lastVisit;
......
}
package com.smart.dao;
import java.io.Serializable;
import java.util.Date;
/** * Created by Mistra.WR on 2017/8/5/005. */
public class LoginLog implements Serializable{
private int loginLogid;
private int userId;
private String ip;
private Date loginDate;
......
}
package com.smart.dao;
import com.smart.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
/** * Created by Mistra.WR on 2017/8/15/015. */
@Repository
public class UserDao {
private JdbcTemplate jdbcTemplate;
private final static String MATCH_COUNT_SQL = "select count(*) from t_user"
+ " where user_name = ? and password=?";
private final static String UPDATE_LOGININFO_SQL = "update t_user set "+
" last_visit=?,last_ip=?,credits=? where user_id=?";
@Autowired //自动注入JdbcTemplate的bean
public void setJdbcTemplatedbcTemplate(JdbcTemplate jdbcTemplate){
this.jdbcTemplate = jdbcTemplate;
}
public int getMatchCount(String userName,String password){
return jdbcTemplate.queryForObject(MATCH_COUNT_SQL,new Object[]{userName,password}, Integer.class).intValue();
}
public User findUserByUserName(final String userName){
String sqlStr = " SELECT user_id,user_name,credits "
+ " FROM t_user WHERE user_name =? ";
final User user = new User();
jdbcTemplate.query(sqlStr, new Object[]{userName},
new RowCallbackHandler() {
public void processRow(ResultSet resultSet) throws SQLException {
user.setUserID(resultSet.getInt("user_id"));
user.setUsername(userName);
user.setCredits(resultSet.getInt("credits"));
}
}
);
return user;
}
public void updateLoginInfo(User user){
jdbcTemplate.update(UPDATE_LOGININFO_SQL,new Object[]{user.getLastVisit(),user.getLastIp(),user.getCredits(),user.getUserID()});
}
}
在前一篇文章:一步一步搭建入门Spring Web应用 中,写完了UserDao之后,还有一个重要的步骤,就是要在Spring容器中装配DAO。在Spring Boot中,这个步骤就不需要了,Boot会自动帮我们装配好。
与前一篇文章一样,UserService。
UserService.java
package com.smart.service;
import com.smart.dao.LoginLogDao;
import com.smart.dao.UserDao;
import com.smart.domain.LoginLog;
import com.smart.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/** * Created by Mistra.WR on 2017/8/10/010. */
@Service
public class UserService {
private UserDao userDao;
private LoginLogDao loginLogDao;
@Autowired
private void setUserDao(UserDao userDao){
this.userDao = userDao;
}
@Autowired
private void setLoginLogDao(LoginLogDao loginLogDao){
this.loginLogDao = loginLogDao;
}
public boolean hasMatcherUser(String username,String password){
int matchCount = userDao.getMatchCount(username,password);
return matchCount > 0;
}
public User findUserByUserName(String username){
return userDao.findUserByUserName(username);
}
@Transactional
public void loginSuccess(User user){
user.setCredits( 5 + user.getCredits());
LoginLog loginLog = new LoginLog();
loginLog.setIp(user.getLastIp());
loginLog.setUserId(user.getUserID());
loginLog.setLoginDate(user.getLastVisit());
userDao.updateLoginInfo(user);
loginLogDao.insertLoginLog(loginLog);
}
}
在编写业务层代码时有两个中啊哟的步骤:一时编写正确的业务逻辑;二是对业务事务的管控。
在Spring Boot中,使用事务非常简单,首先在主类Application上标注@EnableTransactionManagement注解(开启事务支持),然后再访问Service方法上标注 @Transactional注解即可。
如果将 @Transactional注解标注在Service类级别上,name当前Service类的所有方法都将被事务增强。
如果用户想自己定义事务管理器,在Application类中添加一个即可。
修改之后的Application主类:
package com.smart;
/** * Created by Mistra.WR on 2017/8/17/017. */
//@Configuration
//@ComponentScan
//@EnableAutoConfiguration
@SpringBootApplication//此注解可以代替上面三个注解
@EnableTransactionManagement//开启事物支持,启用注解事物管理
public class Application{
public static void main(String[] args) throws Exception{
SpringApplication.run(Application.class,args);
}
@Bean
public PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
在Application中添加自定义事务管理器方法txManager(),并在方法上标注@Bean注解,此时Spring Boot会加载自定义的事务管理器,不会重新实例化其它事务管理器。
由于使用了JSP作为视图,用到了JSTL标签,因此pom.xml需要添加相关依赖包。
<dependency>
<groupId>org.apache.tomcat.embedgroupId>
<artifactId>tomcat-embed-jasperartifactId>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
dependency>
在Boot环境中配置MVC很简单,只需要将上面的主类Application稍作修改。
package com.smart;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/** * Created by Mistra.WR on 2017/8/17/017. */
//@Configuration
//@ComponentScan
//@EnableAutoConfiguration
@SpringBootApplication//此注解可以代替上面三个注解
@EnableTransactionManagement//开启事物支持,启用注解事物管理
public class Application extends SpringBootServletInitializer {//①
public static void main(String[] args) throws Exception{
SpringApplication.run(Application.class,args);
}
//②
protected SpringApplicationBuilder configure(SpringApplicationBuilder application){
return application.sources(Application.class);
}
@Bean
public PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
在①处继承了Spring Boot提供的Servlet初始化器SpringBootServletInitializer,在②处重写了SpringBootServletInitializer的configure()方法。
与前面一篇文章的LoginController一致。
LoginCommand.java
package com.smart.web;
/** * Created by Mistra.WR on 2017/8/14/014. */
public class LoginCommand {
private String username;
private String password;
......
}
LoginController.java
package com.smart.web;
import com.smart.domain.User;
import com.smart.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/** * Created by Mistra.WR on 2017/8/14/014. */
@Controller
public class LoginController {
private UserService userService;
@Autowired
public void setUserService(UserService userService){
this.userService = userService;
}
//负责处理/index.html的请求
@RequestMapping(value = {"/" , "/index.html"})//可配置多个映射路径
public String loginPage(){
return "login";
}
//负责处理/loginCheck.html的请求
@RequestMapping(value = "/loginCheck.html")
public ModelAndView loginCheck(HttpServletRequest request,LoginCommand loginCommand){
boolean isValidUser = userService.hasMatcherUser(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");
}
}
}
在src/main/webapp/WEB-INF目录下创建一个jsp文件夹,跟前面一篇文章的两个jsp页面一样(login.jsp和main.jsp),就不列代码了。
规划好视图目录后,最后一步就是崽application.properties中配置创建好的视图路径。
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
在Maven Projects面板中双击spring-boot:run命令,即可启动应用。