Spring Boot入门,一步一步简化,实现Spring Web项目开发

在此之前写过一篇文章 一步一步搭建入门Spring Web应用,本篇文章就是在此基础上,运用Spring Boot来简化Spring Web开发。本篇文章中有些类可能会联系到前面一篇文章中出现的类。


一、 Spring Boot介绍

Spring Boot诞生的目的就是用来简化Spring应用开发过程。该框架使用了特定的方式来进行配置,从而使得开发人员不在需要定义一系列样板化的配置文件,而专注于核心业务开发。帮助开发人员快速的构建出基于Spring的应用。它会在后台整合项目所需的第三方依赖类库或框架,不再需要编写复杂的XML配置文件,仅通过几行代码就能实现一个可运行的Web应用。

  • 直接嵌入 Tomcat 或 Jetty 服务器,不需要部署 WAR 文件。
  • 提供许多基于Maven的 POM配置模板来简化工程配置。
  • 提供可以直接在生产环境中使用的功能,如性能指标、应用信息和应用健康检查。
  • 提供实现自动化配置的基础设施

Spring Boot启动器。Spring Boot是由一系列启动器组成的,这些启动器构成一个强大的灵活的开发助手。开发人员根据项目需要,选择并组合相应的启动器,就可以快速搭建一个适合项目需要的基础运行框架。
常用Spring Boot启动器:

  1. spring-boot-starter 核心模块,包含自动配置支持、日志库和对 YAML 配置文件的支持。
  2. spring-boot-starter-aop 支持面向切面编程(AOP),包含 spring-aop 和 AspectJ 。
  3. spring-boot-starter-data-mongodb 包含 spring-data-mongodb 来支持 MongoDB。
  4. spring-boot-starter-redis 支持Redis键值存储数据库,包含spring-redis
  5. spring-boot-starter-jdbc 支持使用 JDBC 访问数据库。
  6. spring-boot-starter-test 包含常用的测试所需的依赖,如 JUnit、Hamcrest、Mockito 和 spring-test 等。
  7. spring-boot-starter-web 支持 Web 应用开发,包含 Tomcat 和 spring-mvc、spring-webmvc
  8. spring-boot-starter-websocket 支持使用 Tomcat 开发 WebSocket 应用。
  9. spring-boot-starter-ws 支持 Spring Web Services。
  10. spring-boot-starter-log4j 添加 Log4j 的支持。
  11. spring-boot-starter-logging 使用 Spring Boot 默认的日志框架 Logback。
  12. spring-boot-starter-mail 支持javax.mail模块
  13. spring-boot-starter-remote-shell 支持远程 SSH命令操作。
  14. spring-boot-starter-tomcat 使用 Spring Boot 默认的 Tomcat 作为应用服务器。
  15. spring-boot-starter-jetty 使用 Jetty 而不是默认的 Tomcat 作为应用服务器。

二、Maven配置

创建好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.0</modelVersion>
  <groupId>com.smart</groupId>
  <artifactId>springBootDemo1</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>springBootDemo1 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <!--①继承Spring Boot默认配置-->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.3.RELEASE</version>
  </parent>
  <dependencies>
    <!--②添加第一个Boot Web启动器-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--③如果想使用Jetty服务器就添加这个依赖,默认使用Tomcat-->
    <!--<dependency>-->
      <!--<groupId>org.springframework.boot</groupId>-->
      <!--<artifactId>spring-boot-starter-jetty</artifactId>-->
    <!--</dependency>-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <!--④配置运行插件-->
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <useSystemClassLoader>false</useSystemClassLoader>
        </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主类

程序包结构图:包结构图

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.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,配置数据库的连接信息。

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中,可以通过两种方式配置数据库连接。

  • 一种是通过自定义连接的方式,如在①处配置了连接所需属性。在默认情况下,Boot启动器自动创建tomcat-jdbc连接池。也可以通过像②处自定义连接池,如DBCP,C3P0。
  • 另外一种是通过JNDI方式设置,如在④处为spring.datasource.jndi-name属性指定一个JNDI连接名称即可。

1、User

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;
    ......
}

2.LoginLog

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;
    ......
}

3.UserDao

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会加载自定义的事务管理器,不会重新实例化其它事务管理器。


六、 展现层实现

1.配置pom.xml依赖

由于使用了JSP作为视图,用到了JSTL标签,因此pom.xml需要添加相关依赖包。

    <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>

2.配置Spring MVC框架

在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()方法。

3.LoginController

与前面一篇文章的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");
        }
    }
}

4.JSP页面

在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命令,即可启动应用。

这里写图片描述

猜你喜欢

转载自blog.csdn.net/axela30w/article/details/77337735