SpringBoot學習筆記

SpringBoot

1、SpringBoot的簡介

1.1 SpringBoot產生的背景

Spring 框架的常見問題是要快速建立一個能夠運行的應用比較麻煩,對於新接觸 Spring 框架的開發人員來講,並不知道如何更好的使用這些組件。css

Spring Boot 是 Spring 框架的一個新的子項目,用於建立 Spring 4.0 項目。它的開發始於 2013 年。2014 年 4 月發佈 1.0.0 版本。它能夠自動配置 Spring 的各類組件,並不依賴代碼生成和 XML 配置文件。Spring Boot 也提供了對於常見場景的推薦組件配置。Spring Boot 能夠大大提高使用 Spring 框架時的開發效率html

Ø 使用Spring boot ,能夠輕鬆的建立獨立運行的程序,很是容易構建獨立的服務組件,是實現分佈式架構、微服務架構利器。java

Ø Spring boot簡化了第三方包的引用,經過提供的starter,簡化了依賴包的配置。mysql

1.2 SpringBoot的優缺點

Ø 輕鬆建立獨立的Spring應用程序。web

Ø 內嵌Tomcat、jetty等web容器,不須要部署WAR文件。spring

Ø 提供一系列的「starter」 來簡化的Maven配置,不須要添加不少依賴sql

Ø 開箱即用,儘量自動配置Spring。mongodb

Name Servlet Version Java Version
Tomcat 8 3.1 Java 7+
Tomcat 7 3.0 Java 6+
Jetty 9.3 3.1 Java 8+
Jetty 9.2 3.1 Java 7+
Jetty 8 3.0 Java6+

2、SpringBoot入門案例

Step01:

解壓一個maven3.5到本地shell

Step02:

修改maven的conf\setting的本地倉庫存儲路徑數據庫

Step03:

修改maven的conf\setting 中遠程倉庫爲阿里雲的

Step04:

把Eclipse中的本地和全局的倉庫文件都改爲conf\setting

Step05:

建立一個 maven war項目(test1)或建立一個 maven jar(test2)。 這兩種均可以,但通常都使用jar,由於spring是用於服務,不建議與jsp使用

+springbootdemo1 pom.xml

+springbootdemo2 pom.xml

Step06:

在pom.xml添加spring-boot-starter-web依賴,如圖

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

spring-boot-starter-parent做用:

在pom.xml中引入spring-boot-start-parent,它能夠提供dependency management,也就是說依賴管理引入之後在申明其它dependency的時候就不須要version了,後面能夠看到。

spring-boot-starter-web做用:springweb 核心組件

Step07:

寫一個控制器以下,而後寫一個main方法,把程序跑起來:

package com.jihaiyang.web.controller;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
​
@RestController//至關於聲明Controller - 提共restful 風格
@EnableAutoConfiguration//自動配置,不須要寫spring的配置文件
class HelloController {
​
    @RequestMapping(value = "hello/{name}")
    public String hello1(@PathVariable("name") String name){
        return name+"Hello,SpringBoot";
    }
    public static void main(String[] args) {
        SpringApplication.run(HelloController.class);//啓動當前控制器
    }
}

Step08:

在瀏覽器中訪問http://localhost:8080/hello

3、SpringBoot的兩種啓動方式

3.1 在每一個控制器中啓動

在控制器配置@EnableAutoConfiguration並使用SpringApplication.run()啓動程序

3.2 建立一個App類

建立一個App類,在App類中配置@EnableAutoConfiguration和組件掃描ComponentScan,

而後使用SpringApplication啓動程序,這樣就能夠訪問多個Controller了.

@RequestMapping("{id}")
@ResponseBody
public User userInfo(@PathVariable(varlue="id") Integer id)
{
    User user=new User("gyf","123");
    return user;
}

建立App類

@ComponentScan(basePackages="com.jihaiyang.web.controller")//controller所在的包進行掃描
@EnableAutoConfiguration//此處只需寫一個,其餘控制器不用寫了
public class App{
    public static void main(String[] args){
        SpringApplication.run(App.class,args);
    }
}

4、SpringBoot的Starter Project Options介紹

spring-boot-starter 核心 POM,包含自動配置支持、日誌庫和對 YAML 配置文件的支持
spring-boot-starter-amqp 經過 spring-rabbit 支持 AMQP
spring-boot-starter-aop 包含 spring-aop 和 AspectJ 來支持面向切面編程(AOP)。
spring-boot-starter-batch 支持 Spring Batch,包含 HSQLDB。
spring-boot-starter-data-jpa 包含 spring-data-jpa、spring-orm 和 Hibernate 來支持 JPA。
spring-boot-starter-data-mongodb 包含 spring-data-mongodb 來支持 MongoDB。
spring-boot-starter-data-rest 經過 spring-data-rest-webmvc 支持以 REST 方式暴露 Spring Data 倉庫。
spring-boot-starter-jdbc 支持使用 JDBC 訪問數據庫
spring-boot-starter-security 包含 spring-security。
spring-boot-starter-test 包含經常使用的測試所需的依賴,如 JUnit、Hamcrest、Mockito 和 spring-test 等。
spring-boot-starter-velocity 支持使用 Velocity 做爲模板引擎。
spring-boot-starter-web 支持 Web 應用開發,包含 Tomcat 和 spring-mvc。
spring-boot-starter-websocket 支持使用 Tomcat 開發 WebSocket 應用。
spring-boot-starter-ws 支持 Spring Web Services
spring-boot-starter-actuator 添加適用於生產環境的功能,如性能指標和監測等功能。
spring-boot-starter-remote-shell 添加遠程 SSH 支持
spring-boot-starter-jetty 使用 Jetty 而不是默認的 Tomcat 做爲應用服務器。
spring-boot-starter-log4j 添加 Log4j 的支持
spring-boot-starter-logging 使用 Spring Boot 默認的日誌框架 Logback
spring-boot-starter-tomcat 使用 Spring Boot 默認的 Tomcat 做爲應用服務器。

spring-boot-starter-web

Ø POM 文件中能夠看到,應用所聲明的依賴不多

Ø 只有一個「org.springframework.boot:spring-boot-starter-web」

Ø 而不是像其餘 Spring 項目同樣須要聲明不少的依賴。

Ø 當使用 Maven 命令「mvn dependency:tree」來查看項目實際的依賴時

Ø 發現其中包含SpringMVC框架、SLF4J、Jackson、Hibernate Validator 和 Tomcat 等依賴。

Ø 這實際上 Spring 推薦的 Web 應用中使用的開源庫的組合。

EnableAutoConfiguration

Ø EnableAutoConfiguration」註解的做用在於讓 Spring Boot 根據應用所聲明的依賴來對 Spring 框架進行自動配置,這就減小了開發人員的工做量。

Ø Spring Boot 推薦採用基於 Java 註解的配置方式,而不是傳統的 XML。只須要在主配置 Java 類上添加「@EnableAutoConfiguration」註解就能夠啓用自動配置。

Ø 註解「@RestController」和」@RequestMapping」由 Spring MVC 提供,用來建立 REST 服務。這兩個註解和 Spring Boot 自己並無關係。

5、Web開發

5.1 靜態資源的訪問

在咱們開發Web應用的時候,須要引用大量的js、css、圖片等靜態資源。

Spring Boot默認提供靜態資源目錄位置需置於classpath下,目錄名需符合以下規則:

/static

/public

/resources

/META-INF/resources

舉例:咱們能夠在src/main/resources/目錄下建立static/imgs,在該位置放置一個圖片文件。啓動程序後,嘗試訪問http://localhost:8080/imgs/d.jpg,訪問時不用加static目錄。如能顯示圖片,配置成功。

5.2 控制器返回JSON格式數據

@RestController
public class UserController{
    @RestMapping("/login")
    @ResponseBody
    public Map<String,Object> login(Sring username,String password){
        Map<String,Object> map=new HashMap<String,Object>();
        if("季海洋".equals(username) && "123".equal(password)){
            map.put("status",true);
            map.put("info","登錄成功");
        }else{
            map.put("status",false);
            map.put("info","用戶名或密碼錯誤");
        }
        return map;
    }
}

5.3 全局捕獲異常

@ExceptionHandler 表示攔截異常。@ControllerAdvicecontroller 的一個輔助類,最經常使用的就是做爲全局異常處理的切面類,能夠指定掃描範圍,約定了幾種可行的返回值,若是是直接返回 model 類的話,須要使用

@ResponseBody 進行 json 轉換。

@ControllerAdvice//切面
public class GlobalExceptionHandler {
    @ExceptionHandler(RuntimeException.class)//捕獲運行時異常
    @ResponseBody
    public Map<String,Object> exceptionHander(){
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status",false);
        map.put("info","系統異常");
        return map;
    }
}

在啓動spring中,配置掃描包爲com.jihaiyang.web

@ComponentScan(basePackages="com.jihaiyang.web")
@EnableAutoConfiguration
public class App{
    public static void main(args){
        SpringApplication.run(App.class,args);
    }
}

 

在某個映射的方法中添加個int i=10/0的算術異常

@RestController
public class UserController{
    @RequestMapping("/login")//映射路徑
    @ResponseBody//響應體-自動返回json格式字符串
    public Map<String,Object> login(String username,String password){
        int i=10/0;
        Map<String,Object> map=new HashMap<String,Object>();
        if("jihaiyang".equals(username) && "123".equals(password)){
            map.put("status",true);
            map.put("info","登陸成功!");
        }else{
            map.put("status",false);
            map.put("info","登陸失敗!");
        }
        return map;
    };
}

 

5.四、渲染Web頁面

模板引擎

在動態HTML實現上Spring Boot依然能夠完美勝任,而且提供了多種模板引擎的默認配置支持,因此在推薦的模板引擎下,咱們能夠很快的上手開發動態網站。

Spring Boot提供了默認配置的模板引擎主要有如下幾種:

1 Thymeleaf

2 FreeMarker

3 Velocity

4 Groovy

5 Mustache

Springboot+freemarker

Spring Boot建議使用這些模板引擎,避免使用JSP,若必定要使用JSP將沒法實現Spring Boot的多種特性,具體可見後文:支持JSP的配置

當你使用上述模板引擎中的任何一個,它們默認的模板配置路徑爲:src/main/resources/templates。固然也能夠修改這個路徑,具體如何修改,可在後續各模板引擎的配置屬性中查詢並修改。

5.5 Freemarker的使用

5.5.1:引入freeMarker的依賴包

<!-- 引入freeMarker的依賴包. -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency> 

5.5.2:寫個控制器,並返回些數據

@Controller//若是訪問freemarker模板,就不要用RestController
@RequestMapping("/stu")
public class StudentController{
    @RequestMapping("/list")
    public String list(Map data){
        HashMap data=new HashMap();
        //添加數據
        data.put("loginname","jihaiyang");
        data.put("age",32);
        ArrayList arrayList = new ArrayList();
        String[][] strings = {
            new String[]{"1001","張三","男"},
            new String[]{"1002","李四","男"},
            new String[]{"1003","王五","男"},
            new String[]{"1004","趙六","男"}
        };
        for (String[] string : strings) {
            HashMap hashMap = new HashMap();
            hashMap.put("id",string[0]);
            hashMap.put("name",string[1]);
            hashMap.put("gender",string[2]);
            arrayList.add(hashMap);
        }
        data.put("stuList",arrayList);
        return "stu/list";
    }
}

 

5.5.3:建立.ftl模板文件

Ø 在src/main/resources/建立一個templates/stu文件夾,後綴爲*.ftl

Ø 掌握如何取值和判斷

list.ftl文件

<!DOCTYPE html>
<html>
    <head lang="en">
        <meta   charset="UTF-8" />
        <title></title>
    </head>
    <body>
        歡迎${loginname}
        <#if age <= 17>小哥
            <#elseif age <= 30>先生
            <#else>大叔
        </#if>登陸
        <table border="1">
            <tr>
                <td>ID</td>
                <td>名字</td>
                <td>性別</td>
            </tr>
            <#list   stuList?sort_by("id")?reverse as stu>
                <tr>
                    <td>   ${stu.id}</td> 
                    <td>   ${stu.name}</td>
                    <td>   ${stu.gender}</td>
                </tr>
             </#list>
        </table>
    </body>
</html>   

5.6 SpringBoot 使用jsp

Step1:建立war maven工程

Step2:pom文件引入如下依賴

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.3.RELEASE</version>
</parent>
<dependencies>
    <!-- SpringBoot 核心組件 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
    </dependency>
</dependencies>

Step3:application.properties建立如下配置

spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp 

Step4:控制器代碼

@Controller
@EnableAutoConfiguration
@RequestMapping("/teacher")
public class TeacherController{
    @RequestMapping("/list")
    public String list(){
        return "list";
    }
    
    public static void main(String[] args){
        SpringApplication.run(TeacherController.class,args);
    }
}

Step5:jsp

application.properties中設置內容以下

spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp

6、數據庫訪問

6.1 SpringBoot使用JDBC

Step1:添加依賴

<!-- JDBC -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 數據庫驅動 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

Step2:application.properties新增配置

#視圖配置
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
#數據庫配置
spring.datasource.url=jdbc:mysql://localhost:3306/day12
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Step3:Service

在com.jihaiyang.service.impl中編寫

@Service
private void registerUser(String username,String password,String email){
    @Autowired
    private JdbcTemplate jdbcTemplate;
    String sql ="insert into user(username,password,email) values(?,?,?)"; 
    jdbcTemplate.update(sql,username,password,email);
}

Step4:Controller

在com.jihaiyang.web.controller編寫

@Controller
@RequestMapping("/user")
public class UserController{
    @Autowire
    IUservice userService;
    
    @RequestMapping("/register")
    @ResponseBody
    public String register(){
        userService.registerUser("root","root","root");
        return "success";
    }
}

 

Step5:App

在com.jihaiyang.app中編寫

@ComponentScan(basePackage={"com.jihaiyang.web","com.jihaiyang.service"})
@EnableAutoConfiguration
public class App{
    public static void main(String[] args){
    SpringApplication.run(App.class,args) ;   
    }
}

 

6.2 使用Mybatis

6.2.1 建立一個maven-jar新項目來說解

6.2.2 pom導入

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- 單元測試 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- mybaties -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- mysql驅動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> 
            </dependency>
    </dependencies>

6.2.3 數據庫配置文件

application.properties文件的配置以下

#數據庫配置
spring.datasource.url=jdbc:mysql://localhost:3306/
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

 

6.2.4 Mapper

com.jihaiyang.Mapper中編寫Mapper接口

public interface UserMapper{
    @Insert("insert into user(username,password) values(#{username},#{password}")
    public void save(@Param("username") String username,@Param("password") String password)
        @Select("select * from user where username=#{username}")
        public User findByUsername(@Param("username") String username);
}

 

※※※※※※※※※※※※

換成xml形式,將這個放入Maper包中

<?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="com.jihaiyang.mapper.UserMapper" ><insert id="save">
        insert into t_user (username,password) VALUES(#{0},#{1})
    </insert>
    <select id="findByUsername" resultType="com.gyf.model.User" parameterType="string">
        select * from t_user where username = #{username,jdbcType=VARCHAR}
    </select>
</mapper>

注意這裏須要在pom中添加下面代碼

<build>
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.xml</include>
      </includes>
    </resource>
  </resources>
</build>

※※※※※※※※※※※※

6.2.4 Controller

package com.jihaiyang.controller;
​
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.gyf.mapper.UserMapper;
import com.gyf.model.User;
​
@Controller
@RequestMapping("/user")
public class UserController {
​
    @Autowired
    private UserMapper userMapper;
    @RequestMapping("/find")
    @ResponseBody
    public User find(String name){
        return userMapper.findByName(name);
    }
    
    @ResponseBody
    @RequestMapping("/add")
    public int add(String name){
        return userMapper.insert(name,"e10adc3949ba59abbe56e057f20f883e");
    }
}

6.2.5 App

package com.jihaiyang.app;
​
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
​
@ComponentScan(basePackages={"com.gyf.controller"})
@MapperScan(basePackages={"com.gyf.mapper"})//掃描Mapper
@EnableAutoConfiguration
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

 

6.3 spring 中使用的事務

只須要加個Transactional註解便可

@Transaction
public class UserServiceImpl implements IUserService{
    @Autowired
    private UserMapper userMapper;
    @Override
    public void register(String username,String password){
        userMapper.save(username,password);
        int i=10/0;
    }
}

 

6.4 配置多數據源

之前是在applicationContext.xml中配置數據源,如今咱們經過註解來配置數據源,在com.jihaiyang包下建立包datasource

6.4.1 配置文件中新增兩個數據源所需的參數

spring.datasource.test1.driverClassName=com.mysql.jdbc.Driver
spring.datasource.test1.url=jdbc:mysql://localhost:3306/dbfirst?useUnicode=true&characterEncoding=utf-8
spring.datasource.test1.username=root
spring.datasource.test1.password=123456
​
spring.datasource.test2.driverClassName=com.mysql.jdbc.Driver
spring.datasource.test2.url=jdbc:mysql://localhost:3306/dbsecond?useUnicode=true&characterEncoding=utf-8
spring.datasource.test2.username=root
spring.datasource.test2.password=123456

數據庫SQL語句以下

use dbone;
CREATE table user(
    id  int PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
    password VARCHAR(50),
    email VARCHAR(50),
  birthday TIMESTAMP
);
​
use dbsecond;
CREATE table customer(
    id  int PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50),
    tel VARCHAR(50)
);
​

 

6.4.2 編寫數據源配置類

dbone數據庫的數據源配置信息

@Configuration//註解到springboot容器中
@MapperScan(basePackages="com.jihaiyang.dbFirst.mapper",sqlSessionFactoryRef="dbFirstSqlSessionFactory")
public class DataSource01 {
​
    /**
     * @return 返回dbFirst數據庫的數據源
     */
    @Bean(name="dbFirstDataSource")
    @Primary//主數據源
    @ConfigurationProperties(prefix="spring.datasource.dbFirst")
    public DataSource dateSource(){
        return DataSourceBuilder.create().build();
    }
​
    /**
     * @return 返回dbFirst數據庫的會話工廠
     */
    @Bean(name = "dbFirstSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dbFirstDataSource") DataSource ds) throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);
​
        return bean.getObject();
    }
​
    /**
     * @return 返回dbFirst數據庫的事務
     */
    @Bean(name = "dbFirstTransactionManager")
    @Primary
    public DataSourceTransactionManager transactionManager(@Qualifier("dbFirstDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
​
    /**
     * @return 返回dbFirst數據庫的會話模版
     */
    @Bean(name = "dbFirstSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(
            @Qualifier("dbFirstSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

dbtwo數據庫的數據源配置信息

@Configuration//註解到springboot容器中
@MapperScan(basePackages = "com.jihaiyang.dbSecond.mapper", sqlSessionFactoryRef = "dbSecondSqlSessionFactory")
public class DataSource02 {
​
    /**
     * @return 返回dbSecond數據庫的數據源
     */
    @Bean(name = "dbSecondDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.dbSecond")
    public DataSource dateSource() {
        return DataSourceBuilder.create().build();
    }
​
    /**
     * @return 返回dbSecond數據庫的會話工廠
     */
    @Bean(name = "dbSecondSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dbSecondDataSource") DataSource ds) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);
​
        return bean.getObject();
    }
​
    /**
     * @return 返回dbSecond數據庫的事務
     */
    @Bean(name = "dbSecondTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("dbSecondDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
​
    /**
     * @return 返回dbSecond數據庫的會話模版
     */
    @Bean(name = "dbSecondSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(
            @Qualifier("dbSecondSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

 

6.4.3 dbSecond mapper & service

public interface CustomerMapper{
    @Insert("insert into customer(name,phone) values(#{name},#{telphone})")
    int insert(@Param("name") String name,@Param("telphone") String telphone)
}

@Service
public class CustomerService{
    @Autowired
    private CustomerMapper customerMapper;
    /*
    *添加一個客戶
    */
    public void add(String name,String telphone){
        customerMapper.insert(name,telphone);
    }
}

 

6.4.4 Controller

@Controller
@RequestMapper("/user")
public class UserController{
    @Autowired
    private UserService userservice;
    @Autowired
    private CustomerService customerService;
    
    @ResponseBody
    @RequestMapping("/add")
    public String add(String name){
        userService.register(name,"123");
        customerService.add(name,"110");
        return "success";
    }
}

 

6.4.5 App

@ComponentScan(basePackages={"com.jihaiyang.datasource","com.jihaiyang.dbone","com.jihaiyang.dbtwo"})
@EnableAutoConfiguration
public class App{
    public static void main(String[] args){
        SpringApplication.run(App.class,args)
    }
}

 

6.5 多數據源問題

驗證代碼就不敲了,結論是一個事務只對當前的數據源有效。

6.6 springboot中的多事務管理

使用springboot+jta+atomikos 分佈式事物管理解決方案

6.6.1 添加jta依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>

6.6.2 修改數據庫鏈接配置數據

# Mysql 1
mysql.datasource.dbfirst.url = jdbc:mysql://localhost:3306/dbone?useUnicode=true&characterEncoding=utf-8
mysql.datasource.dbfirst.username = root
mysql.datasource.dbfirst.password = 123456
​
mysql.datasource.dbfirst.minPoolSize = 3
mysql.datasource.dbfirst.maxPoolSize = 25
mysql.datasource.dbfirst.maxLifetime = 20000
mysql.datasource.dbfirst.borrowConnectionTimeout = 30
mysql.datasource.dbfirst.loginTimeout = 30
mysql.datasource.dbfirst.maintenanceInterval = 60
mysql.datasource.dbfirst.maxIdleTime = 60
​
mysql.datasource.dbfirst.testQuery = select 1
# Mysql 2
mysql.datasource.dbsecond.url =jdbc:mysql://localhost:3306/dbsecond?useUnicode=true&characterEncoding=utf-8
mysql.datasource.dbsecond.username =root
mysql.datasource.dbsecond.password =123456
mysql.datasource.dbsecond.minPoolSize = 3
mysql.datasource.dbsecond.maxPoolSize = 25
mysql.datasource.dbsecond.maxLifetime = 20000
mysql.datasource.dbsecond.borrowConnectionTimeout = 30
mysql.datasource.dbsecond.loginTimeout = 30
mysql.datasource.dbsecond.maintenanceInterval = 60
mysql.datasource.dbsecond.maxIdleTime = 60
mysql.datasource.dbsecond.testQuery = select 1

 

6.6.3 添加2個配置模型

模型放在com.jihaiyang.dbconfig包 dbFirst數據源模型

@ConfigurationProperties("mysql.datasource.dbfirst")
public class DBConfig1 {
    private String url;
    private String username;
    private String password;
    private int minPoolSize;
    private int maxPoolSize;
    private int maxLifetime;
    private int borrowConnectionTimeout;
    private int loginTimeout;
    private int maintenanceInterval;
    private int maxIdleTime;
    private String testQuery;
}

dbSecond數據源模型

@ConfigurationProperties("mysql.datasource.dbsecond")
public class DBConfig2 {
    private String url;
    private String username;
    private String password;
    private int minPoolSize;
    private int maxPoolSize;
    private int maxLifetime;
    private int borrowConnectionTimeout;
    private int loginTimeout;
    private int maintenanceInterval;
    private int maxIdleTime;
    private String testQuery;
}

6.6.4 設定兩個數據源具體的參數

dbfirst數據庫的數據源

package com.jihaiyang.datasource;
​
import java.sql.SQLException;
import javax.sql.DataSource;
​
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
​
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.jihaiyang.dbconfig.DBConfig1;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
​
@Configuration//註解到springboot容器中
@MapperScan(basePackages = "com.jihaiyang.dbFirst.mapper", sqlSessionFactoryRef = "dbFirstSqlSessionFactory")
public class DataSource01 {
​
    // 配置數據源
    @Primary
    @Bean(name = "dbFirstDataSource")
    public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
        mysqlXaDataSource.setUrl(testConfig.getUrl());
        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
        mysqlXaDataSource.setPassword(testConfig.getPassword());
        mysqlXaDataSource.setUser(testConfig.getUsername());
        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
​
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXaDataSource);
        xaDataSource.setUniqueResourceName("dbFirstDataSource");
​
        xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
        xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
        xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
        xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
        xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
        xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
        xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
        xaDataSource.setTestQuery(testConfig.getTestQuery());
        return xaDataSource;
    }
​
    @Bean(name = "dbFirstSqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("dbFirstDataSource") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }
​
    @Bean(name = "dbFirstSqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(
            @Qualifier("dbFirstSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

dbsecond數據庫的數據源

package com.jihaiyang.datasource;
import java.sql.SQLException;
import javax.sql.DataSource;
​
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.gyf.dbconfig.DBConfig2;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
​
@Configuration//註解到springboot容器中
@MapperScan(basePackages = "com.gyf.dbSecond.mapper", sqlSessionFactoryRef = "dbSecondSqlSessionFactory")
public class DataSource02 {
​
    // 配置數據源
    @Bean(name = "dbSecondDataSource")
    public DataSource testDataSource(DBConfig2 testConfig) throws SQLException {
        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
        mysqlXaDataSource.setUrl(testConfig.getUrl());
        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
        mysqlXaDataSource.setPassword(testConfig.getPassword());
        mysqlXaDataSource.setUser(testConfig.getUsername());
        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
​
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXaDataSource);
        xaDataSource.setUniqueResourceName("dbSecondDataSource");
​
        xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
        xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
        xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
        xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
        xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
        xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
        xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
        xaDataSource.setTestQuery(testConfig.getTestQuery());
        return xaDataSource;
    }
​
    @Bean(name = "dbSecondSqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("dbSecondDataSource") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }
​
    @Bean(name = "dbSecondSqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(
            @Qualifier("dbSecondSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

七 整合Log4j

7.1 導入Log4j屬性文件

log4j.properties

注意,複製時要把每一行後面的空格去除

log4j.rootLogger=INFO,Console,File   
log4j.appender.Console=org.apache.log4j.ConsoleAppender  
log4j.appender.Console.Target=System.out
log4j.appender.Console.layout=org.apache.log4j.PatternLayout  
log4j.appender.Console.layout.ConversionPattern=[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c - %L]%m%n
 
log4j.appender.File=org.apache.log4j.RollingFileAppender  
log4j.appender.File.File=C:/Users/10301/Desktop/test/logs/info/info.log 
log4j.appender.File.MaxFileSize=10MB  
 
log4j.appender.File.Threshold=ALL  
log4j.appender.File.layout=org.apache.log4j.PatternLayout  
log4j.appender.File.layout.ConversionPattern=[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c - %L]%m%n 

7.2 pom.xml

去除springboot的logging,添加log4j,由於自帶的logging不啓效果

springboot下的Log4j的版本最新1.3.8,若是你的springboot的parent版本太高,那在在添加log4j本身版本 。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusiions>
        <exclusion>
            <groupID>org.springframework.boot</groupID>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusiions>
</dependency>

添加本身的log4j版本

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j</artifactId>
    <version>1.3.8 RELEASE</version>
</dependency>

7.3 測試

@Autowired
private UserService userService;
Logger logger=Logger.getLogger(UserService.class);
@ResponseBody
@RequestMapping("/add")
public String add(String name){
    logger.info("this is test information !"+"@@Hello :"+name);
    return "success";
}

8. 使用AOP統一處理Web請求日誌

Step01

<!-- AOP -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Step02:寫個切面類

package com.jihaiyang.aop;
​
import java.util.Enumeration;
​
import javax.servlet.http.HttpServletRequest;
​
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Aspect
@Component
public class WebLogAspect {
    private Logger logger = Logger.getLogger(getClass());
    
    @Pointcut("execution(public * com.gyf.controller..*.*(..))")
    public void webLog() {
    
    }
    
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到請求,記錄請求內容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 記錄下請求內容
        logger.info("---------------request----------------");
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        Enumeration<String> enu = request.getParameterNames();
        while (enu.hasMoreElements()) {
            String name = (String) enu.nextElement();
            logger.info("name:" + name + "value" + request.getParameter(name));
        }
    }
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        logger.info("---------------response----------------");
        // 處理完請求,返回內容
        logger.info("RESPONSE : " + ret);
    }
}

 

Step3:App

在App類中添加對該AOP類的掃描

8. 修改端口號

在application.properties中

server.port=8888 
server.context-path=/test

在application.yml中

注意冒號後的只能用空格,不能用tab

server:
  port:  8090
  context-path: /test-yml

Springboot 打包部署

  1. 先打成war包或者jar包

  2. 使用java -jar test3-0.0.1-SNAPSHOT.jar 運行便可

打包時添加下面依賴代碼

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>utf-8</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>com.gyf.app.App</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

 

在終端要中止服務器時,使用Ctrl + C。直接點x,會端口沒有關掉。

相關文章
相關標籤/搜索