1. 程式人生 > 實用技巧 >Java學習之SpringBoot

Java學習之SpringBoot

什麼是SpringBoot

SpringBoot是Spring專案中的一個子工程,與我們所熟知的Spring-framework 同屬於spring的產品:

把Spring Boot稱為搭建程式的腳手架。其最主要作用就是幫我們快速的構建龐大的spring專案,並且儘可能的減少一切xml配置,做到開箱即用,迅速上手,讓我們關注於業務而非配置。

我們可以使用SpringBoot建立java應用,並使用java –jar 啟動它,就能得到一個生產級別的web工程。

特點:

  • 建立獨立的spring應用程式

  • 直接內嵌tomcat、jetty和undertow(不需要打包成war包部署)

  • 提供了固定化的“starter”配置,以簡化構建配置

  • 儘可能的自動配置spring和第三方庫

  • 提供產品級的功能,如:安全指標、執行狀況監測和外部化配置等

  • 絕對不會生成程式碼,並且不需要XML配置

專案Demo

新增啟動器:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>

新增測試:

@RestController
@EnableAutoConfiguration
public class MyController {

    @GetMapping("hello")
    public String test(){
        return "HelloWorld!";
    }

    public static void main(String[] args) {
        SpringApplication.run(MyController.class,args);
    }
}

執行後,在瀏覽器輸入地址:http://localhost:8080/hello

結果:

注意:SpringBoot啟動需要先關閉上一個再啟動!

上述demo只有一個controller,可以進行優化:

啟動類:

@SpringBootApplication
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

測試類:

@RestController
public class MyController {

    @GetMapping("hello")
    public String test(){
        return "First SpringBoot";
    }
}
@RestController
public class MyController2 {

    @GetMapping("hello2")
    public String test(){
        return "Second SpringBoot";
    }
}

結果:

補充:

@EnableAutoConfiguration

開啟spring應用程式的自動配置,SpringBoot基於你所新增的依賴和你自己定義的bean,試圖去猜測並配置你想要的配置。比如我們引入了`spring-boot-starter-web`,而這個啟動器中幫我們添加了`tomcat`、`SpringMVC`的依賴。此時自動配置就知道你是要開發一個web應用,所以就幫你完成了web及SpringMVC的預設配置了!

總結,SpringBoot內部對大量的第三方庫或Spring內部庫進行了預設配置,這些配置是否生效,取決於我們是否引入了對應庫所需的依賴,如果有那麼預設配置就會生效。所以,我們使用SpringBoot構建一個專案,只需要引入所需依賴,配置就可以交給SpringBoot處理了。

@SpringBootApplication

@SpringBootApplication其實是一個組合註解,這裡重點的註解有3個:

  • @SpringBootConfiguration(來聲明當前類是SpringBoot應用的配置類,專案中只能有一個,所以一般我們無需自己新增。)

  • @EnableAutoConfiguration:開啟自動配置

  • @ComponentScan:開啟註解掃描

配置檔案

SpringBoot使用一個全域性的配置檔案,配置檔名是固定的,檔案命名主要分為以下兩種(任選其一):

•application.properties

•application.yml

完整專案

專案結構:

pom.xml:

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.demo.myspringboot</groupId>
    <artifactId>myspringboot</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.28</version>
        </dependency>
        <!--預設使用HikariCP連線池-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>2.1.5.RELEASE</version>
        </dependency>
        <!--不要忘記資料庫驅動,因為springboot不知道我們使用的什麼資料庫,這裡選擇mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <!--mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
    </dependencies>
</project>
pom.xml

application.properties:

# 連線四大引數
spring.datasource.url=jdbc:mysql://localhost:3306/bgblog
spring.datasource.username=root
spring.datasource.password=root
# 可省略,SpringBoot自動推斷
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.minimum-idle=10

# mybatis 別名掃描
mybatis.type-aliases-package=com.demo.bean.User
# mapper.xml檔案位置,如果沒有對映檔案,請註釋掉
mybatis.mapper-locations=classpath:mappers/*.xml

#thymeleaf
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false
application.properties

index.html(首頁):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>HelloWorld!</h1>
<form method="post" action="/user">
    <button type="submit">查詢使用者</button>
</form>
</body>
</html>
index.html

User.html(Thymeleaf 靜態頁面):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
    <style type="text/css">
        table {border-collapse: collapse; font-size: 14px; width: 80%; margin: auto}
        table, th, td {border: 1px solid darkslategray;padding: 10px}
    </style>
</head>
<body>
<div style="text-align: center">
    <span style="color: darkslategray; font-size: 30px">歡迎光臨!</span>
    <hr/>
    <table class="list">
        <tr>
            <th>id</th>
            <th>姓名</th>
            <th>電話</th>
            <th>密碼</th>
        </tr>
        <tr th:each="user : ${users}">
            <td th:text="${user.userId}">1</td>
            <td th:text="${user.userName}">張三</td>
            <td th:text="${user.phoneNum}">110</td>
            <td th:text="${user.passWorld}">888</td>
        </tr>
    </table>
</div>
</body>
</html>
User.html

UserMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
    mapper標籤:配置各類宣告
    namespace:名稱空間,由於對映檔案有多個,為了防止crud語句的唯一標識被重複,可以設定空間名稱。
 -->
<mapper namespace="com.demo.Mapper.UserMapper">
    <!--
    select:查詢的statement(宣告),用來編寫查詢語句
    id:語句的唯一標識
    resultType:配置返回的結果集型別
    parameterType:傳遞的引數型別,可以省略
    -->
    <select id="queryUserById" resultType="com.demo.bean.User">
        select * from user where userId = #{id}
    </select>
    <select id="queryUserList" resultType="com.demo.bean.User">
        select * from user
    </select>
    <!--
          insert:插入的statement,編寫插入語句
          id:插入語句的唯一標識
          parameterType:插入語句的引數,可以省略
       -->
    <insert id="insertUser">
        insert into user VALUES (
        #{userId},
        #{userName},
        #{phoneNum},
        #{passWorld}
        );
    </insert>
    <!--
    update:更新的statement,用來編寫更新語句
    id:語句的唯一標識
    parameterType:語句的引數,可以省略
 -->
    <update id="updateUser">
        update user set userName =   #{userName} where userId = #{userId};
    </update>
    <!--
    delete:刪除的statement,用來編寫刪除語句
    id:語句的唯一標識
    parameterType:語句的引數,可以省略
 -->
    <delete id="deleteUserById">
        delete from user where userId = #{id};
    </delete>

</mapper>
UserMapper.xml

TestApplication:

/**
 * 啟動器
 * */
@SpringBootApplication
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}
TestApplication

User:

@Component
public class User {
    private String userId;
    private String userName;
    private String phoneNum;
    private String passWorld;

    public User() {
    }

    public User(String userId, String userName, String phoneNum, String passWorld) {
        this.userId = userId;
        this.userName = userName;
        this.phoneNum = phoneNum;
        this.passWorld = passWorld;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }

    public void setPassWorld(String passWorld) {
        this.passWorld = passWorld;
    }

    public String getUserId() {
        return userId;
    }

    public String getUserName() {
        return userName;
    }

    public String getPhoneNum() {
        return phoneNum;
    }

    public String getPassWorld() {
        return passWorld;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId='" + userId + '\'' +
                ", userName='" + userName + '\'' +
                ", phoneNum='" + phoneNum + '\'' +
                ", passWorld='" + passWorld + '\'' +
                '}';
    }
}
User

DefaultPage(設定預設頁面):

/**
 * 設定預設頁面
 * */
@Configuration
public class DefaultPage extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers( ViewControllerRegistry registry )
    {
        registry.addViewController( "/" ).setViewName( "forward:/index.html" );
        registry.setOrder( Ordered.HIGHEST_PRECEDENCE );
        super.addViewControllers( registry );
    }
}
DefaultPage

JdbcConfiguration(獲取資料來源):

/**
 * 獲取資料來源
 * */
@Configuration
public class JdbcConfiguration {

    // 宣告要注入的屬性字首,SpringBoot會自動把相關屬性通過set方法注入到DataSource中
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }
}
JdbcConfiguration

MVCConfiguration(設定攔截器):

/**
 * 設定攔截器
 * */
@Configuration
public class MVCConfiguration implements WebMvcConfigurer{

    @Autowired
    private MyInterceptor myInterceptor;
    /**
     * 重寫介面中的addInterceptors方法,新增自定義攔截器
     * @param registry
     */
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/**");
    }
}
MVCConfiguration

MyInterceptor(攔截器物件):

/**
 * 攔截器
 * */
@Component
public class MyInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle method is running!");
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle method is running!");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion method is running!");
    }
}
MyInterceptor

JdbcProperties(資料來源屬性物件):

/**
 * 資料來源屬性獲取
 * */
@ConfigurationProperties(prefix = "spring.datasource")
public class JdbcProperties {
    private String url;
    private String driverClassName;
    private String username;
    private String password;

    public String getUrl() {
        return url;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public void setUrl(String url) {

        this.url = url;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public JdbcProperties(String url, String driverClassName, String username, String password) {

        this.url = url;
        this.driverClassName = driverClassName;
        this.username = username;
        this.password = password;
    }

    public JdbcProperties() {

    }
}
JdbcProperties

MyController:

/**
 * 測試Controller
 * */
@Controller
public class MyController {

    @Autowired
    private DataSource dataSource;
    @Autowired
    private UserService userService;

    @RequestMapping("/user")
    public String all(ModelMap model) {
        // 查詢使用者
        List<User> users = this.userService.queryUserList();
        // 放入模型
        model.addAttribute("users", users);
        // 返回模板名稱(就是classpath:/templates/目錄下的html檔名)
        return "User";
    }
}
MyController

UserService:

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryUserById(String id){
        User user = userMapper.queryUserById(id);
        return user;
    }
    public List<User> queryUserList(){
        List<User> users = userMapper.queryUserList();
        return users;
    }

    public void insertUser(User user){
        userMapper.insertUser(user);
    }
    public void updateUser(User user){
        userMapper.updateUser(user);
    }

    public void deleteUserById(String id){
        userMapper.deleteUserById(id);
    }
}
UserService

UserMapper:

@Mapper
@Component
public interface UserMapper {
    /**
     * 通過id查詢user物件
     * @param id
     * @return
     */
    User queryUserById(String id);
    /**
     * 查詢所有使用者
     * @return
     */
    List<User> queryUserList();

    /**
     * 插入使用者
     * @param user
     */
    void insertUser(User user);

    /**
     * 更新使用者
     * @param user
     */
    void updateUser(User user);
    /**
     * 通過id刪除使用者
     * @param id
     */
    void deleteUserById(String id);
}
UserMapper