SpringBoot從入門到高級

前言: 學習SpringBoot不該該直接就是開始使用SpringBoot,若是直接拿來用確定會有不少人不是很明白特別剛開始入門的,固然官網上也有快速上手的教程可是官網上跨度有點大,在這片文章中爲主要是從之前沒使用SpringBoot以前咱們怎麼作的以及慢慢的引入SpringBoot,我但願經過本身的體會和認識來幫助更多朋友來學習SpringBoothtml

目錄結構前端

  • SpringJavaConfig
    • @Configuration和基礎的@Bean
    • @ComponentScan和測試
    • @Bean標籤屬性詳解
    • @Import標籤
    • XML和Annotation的混用
    • 其餘經常使用標籤(@PropertySource和@PropertySources,@Profile和@ActiveProfile)
  • 第一個HelloWorld
  • Springboot簡介
  • Springboot基本使用
    • 應用構建
    • SpringApplication
    • 參數配置
  • 日誌
    • 默認日誌
    • 外部日誌框架LogBack
  • Springboot開發WEB應用
    • 靜態資源
    • Freemarker集成
    • 錯誤處理
    • mybatis集成
    • 事務處理
    • 文件上傳

首先了解 Spring Java Config(Spring的java配置)

(在這裏咱們先以最原始的方式來建立項目和測試) 建立一個Maven項目添加依賴和加入配置文件application.xml SomeBean.javajava

public class SomeBean {}
複製代碼

application.xmlmysql

<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
		<bean id="someBean" class="com.jd.javaconfig.SomeBean"></bean>
     </beans>
複製代碼

這個是基於XML配置的方式 MyTest.javaweb

public class MyTest {
	@Test
	public void test1(){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("application.xml");
		SomeBean sb = ctx.getBean(SomeBean.class);
		System.out.println(sb);
	}
}
複製代碼

上面是咱們最簡單的一個Spring Demoredis

下面經過標籤來配置Spring OtherBean.javaspring

public class OtherBean {}
複製代碼

下面咱們寫了一個方法返回一個SomeBean的對象咱們要告訴Spring這個方法是Spring幫咱們管理的bean經過@Bean標籤sql

AppConfig .java數據庫

// 做爲Spring的主配置文件
    //@Configuration標籤表示這個類可被Spring識別的配置對象的類,只有有這個標記的標籤的類才能使用@Bean標籤做用於對應的方法上面
    @Configuration
    public class AppConfig {
	//@Bean標籤表示讓Spring幫咱們管理bean
	@Bean
	public SomeBean someBean(){
		return new SomeBean();
	}
	@Bean
	public OtherBean otherBean(){
		return new 	OtherBean();
	}
    }
複製代碼

不像上一個demo,這個是基於AnnotationConfigApplicationContext來配置的 MyTest.javaexpress

@Test
public void test() {
	ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
	SomeBean sb = ctx.getBean(SomeBean.class);
	OtherBean ob = ctx.getBean(OtherBean.class);
	System.out.println(sb);
	System.out.println(ob);
}
複製代碼

到這裏咱們就已經學完了兩個重要的標籤 @Configuration和@Bean, @Configuration標籤表示這個類可被Spring識別的配置對象的類,只有有這個標記的標籤的類才能使用 @Bean標籤做用於對應的方法上面 @Bean(destroyMethod = "destory", initMethod = "init")也能夠經過這樣的寫法來配置bean的初始化方法和銷燬方法

@Component標籤
@Component
public class SomeBean {}
複製代碼

@Component
public class OtherBean {}
複製代碼

//@Configuration標籤表示這個類可被Spring識別的配置對象的類,這有有這個標記的標籤的類才能使用@Bean標籤做用於對應的方法上面
// @ComponentScan:開啓組件自動掃描;默認狀況下,它會掃描當前類所在的包及其子包中的全部標籤對象加載到Spring容器
@Configuration
@ComponentScan(basePackages="com.jd.scan")
public class AppConfig {}
複製代碼

public class MyTest {
@Test
public void test() {
	ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
	SomeBean sb = ctx.getBean(SomeBean.class);
	OtherBean ob = ctx.getBean(OtherBean.class);
	System.out.println(sb);
	System.out.println(ob);
}
}
複製代碼

@ComponentScan:開啓組件自動掃描;默認狀況下,它會掃描當前類所在的包及其子包中的全部標籤對象加載到Spring容器

對象的關係引用

在someBean裏依賴一個otherBean

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyTest {
@Autowired
@Qualifier("somebean")
private SomeBean somebean;
  //@Autowired
 //@Qualifier("somebean2")
 //private SomeBean somebean2;
@Test
public void test() {
	System.out.println(somebean.getOtherBean());
 //System.out.println(somebean2.getOtherBean());
}
}
複製代碼

@Configuration
    public class AppConfig {
//第一種方式(對象的注入)
@Bean(destroyMethod = "destory", initMethod = "init")
public SomeBean somebean(OtherBean otherbean) {
	SomeBean sBean = new SomeBean();
	sBean.setOtherBean(otherbean);
	return sBean;
  }
//第二種方式
  //	@Bean
 //	public SomeBean somebean2() {
 //		SomeBean sBean = new SomeBean();
  //		sBean.setOtherBean(otherbean());
  //		return sBean;
 //	}

@Bean
public OtherBean otherbean() {
	return new OtherBean();
}
}
複製代碼

使用try來關閉容器

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=AppConfig.class)
public class MyTest2 {
@Test
public void test() {
	try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class)) {
		SomeBean sb = context.getBean(SomeBean.class, "somebean");
		System.out.println(sb);
	}
}
}
複製代碼
@import標籤
public class MyDataSource {}
複製代碼

public class MyRedisTemplate {}
複製代碼

@Configuration
public class ConfigRedis {
@Bean
public MyRedisTemplate myRedisTemplate(){
	return new MyRedisTemplate();
}
}
複製代碼

@Configuration
public class ConfigDataSource {
@Bean
public MyDataSource myDatasource(){
return new MyDataSource();	
}
}
複製代碼

AppConfig這個類由於打上@Configuration標籤因此是主配置文件,他須要鏈接着兩個類ConfigDataSource.class,ConfigRedis.class 只須要使用@Import 標籤就能夠表示導入類

@Configuration
@Import({ConfigDataSource.class,ConfigRedis.class})
public class AppConfig {
}
複製代碼

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyTest {
@Autowired
private MyDataSource datasource;
@Autowired
private MyRedisTemplate redisTemplate;
@Test
public void test(){
	System.out.println(datasource);
	System.out.println(redisTemplate);
}
}
複製代碼
@importresource標籤 在javaconfig中混用xml

OtherBean.java

public class OtherBean {}
複製代碼

application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="otherbean" class="com.jd.importresource.OtherBean" />	
</beans>
複製代碼

SomeBean.java

@Setter@Getter
public class SomeBean {

private OtherBean otherBean;

public void init() {
	System.out.println("===init====");
}

public void destory() {
	System.out.println("====destory=====");
}
}
複製代碼

AppConfig.java

@Configuration
// @importresource標籤來在javaconfig中混用xml config
@ImportResource("classpath:com/jd/importresource/application.xml")
public class AppConfig {
@Bean(destroyMethod = "destory", initMethod = "init")
public SomeBean somebean(OtherBean otherbean) {
	SomeBean sBean = new SomeBean();
	sBean.setOtherBean(otherbean);
	return sBean;
}
}
複製代碼

MyTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
 public class MyTest {
@Autowired
private SomeBean somebean;

@Test
public void test() {
	System.out.println(somebean.getOtherBean());
}
}
複製代碼

@ImportResource("classpath:com/jd/importresource/application.xml") 經過使用@ImportResource標籤來導入資源

引入外部的.properties資源文件(2種方式)

db.properties

db.username=username
db.password=password
db.url=url
db.driverClass=driverClass
複製代碼

MyDatasource .java

@Setter@Getter@ToString@AllArgsConstructor
public class MyDatasource {

private String username;
private String password;
private String url;
private String driverClass;
}
複製代碼

第一種方式

AppConfig .java

@Configuration
 // @PropertySource表明引入外部的.properties資源文件
 //@PropertySources嵌套@PropertySource引入多個外部資源文件

@PropertySource("classpath:com/jd/properties/db.properties")
public class AppConfig {

@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
@Value("${db.url}")
private String url;
@Value("${db.driverClass}")
private String driverClass;

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer (){
	return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public MyDatasource datasource(){
	return new MyDatasource(username, password, url, driverClass);

}
}
複製代碼

MyTest .java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyTest {

@Autowired
private MyDatasource datasource;

@Test
public void test() {
	System.out.println(datasource);
}
}
複製代碼

第二種方式

@Configuration
 // @PropertySource表明引入外部的.properties資源文件
 //@PropertySources嵌套@PropertySource引入多個外部資源文件

@PropertySource("classpath:com/jd/properties/db.properties")
public class AppConfig {
 //Environment表明spring的環境,在環境裏面只有兩種東西: 1,讀入的外部資源文件(properties); 2,profile
 
@Autowired
private Environment env;

@Bean
public MyDatasource datasource() {
	return new MyDatasource(env.getProperty("db.username"), env.getProperty("db.password"),
			env.getProperty("db.url"), env.getProperty("db.driverClass"));
}
}
複製代碼
profile

db-dev.properties db-profile.properties

db.username=username
db.password=password
db.url=url
db.driverClass=driverClass  
複製代碼

MyDatasource.java

@Setter@Getter@ToString@AllArgsConstructor
public class MyDatasource {

private String username;
private String password;
private String url;
private String driverClass;
}
複製代碼

//生產環境的配置對象
@Configuration
@Profile("pro")
@PropertySource("classpath:com/jd/profile/db-pro.properties")
public class ConfigPro {

@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
@Value("${db.url}")
private String url;
@Value("${db.driverClass}")
private String driverClass;
@Bean
public MyDatasource datasource() {
	return new MyDatasource(username, password, url, driverClass);
}
}
複製代碼

//針對開發環境的配置
@Configuration
@Profile("dev")
@PropertySource("classpath:com/jd/profile/db-dev.properties")
public class ConfigDev {

@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
@Value("${db.url}")
private String url;
@Value("${db.driverClass}")
private String driverClass;

@Bean
public MyDatasource datasource() {
	return new MyDatasource(username, password, url, driverClass);
}
}
複製代碼

AppConfig .java

@Configuration
@Import({ ConfigDev.class, ConfigPro.class })
public class AppConfig {

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
	return new PropertySourcesPlaceholderConfigurer();
}
}
複製代碼

MyTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
@ActiveProfiles("dev")
public class MyTest {
@Autowired
private MyDatasource datasource;
@Test
public void test() {
	System.out.println(datasource);
}
}
複製代碼

到這裏咱們把須要回顧和拓展的知識都有必定加深下面咱們開始正式學習SpringBoot

SpringBoot的HelloWorld

先演示在地址欄訪問loclhost:8080/hello返回字符串hello world #####1.在pom.xml文件中加入依賴

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.5.6.RELEASE</version>
</parent>

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
</dependencies>
複製代碼
2.建立一個Controller:

HelloSpringBoot.java

@SpringBootApplication
@Controller
public class HelloSpringBoot {
@RequestMapping("hello")
@ResponseBody
public String hello() {
	return "hello world";
}

public static void main(String[] args) {
	SpringApplication.run(HelloSpringBoot.class, args);
}
}
複製代碼

Snip20170910_30.png

#####3.運行 main方法 . ____ _ __ _ _ /\ / ' __ _ () __ __ _ \ \ \
( ( )_
_ | '_ | '| | ' / ` | \ \ \
\/ )| |)| | | | | || (| | ) ) ) ) ' |
| .__|| ||| |_, | / / / / =========||==============|/=//// :: Spring Boot :: (v1.5.6.RELEASE)

分析: 1,繼承spring-boot-starter-parent,引入基本的依賴管理配置; 2,引入spring-boot-starter-web,自動引入了springweb相關的包; 3,@SpringBootApplication:這個註解告訴springboot自動的去完成相關配置,包括基礎類的加載,bean的掃描等等,這個後面詳細介紹;簡單理解爲這個標籤爲咱們的應用配置完成了不少基本功能; 4,SpringApplication.run:這個是springboot爲咱們提供的最大的區別,在於springboot再也不是一個web應用,須要咱們本身去打包,部署,啓動tomcat,springboot默認把tomcat打包到應用中,咱們能夠以正常的運行jar的方式來運行springboot應用;

應用獨立運行: 1,pom文件中添加:

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>
複製代碼

2,使用package命令打包,在命令行中使用java -jar xx.jar運行;注意,必定要引入spring-boot-maven-plugin以後運行package打包才能正常運行;

3,直接使用maven插件:spring-boot:run運行;

Springboot的優缺點 1. 建立獨立的Spring應用程序 2. 嵌入的Tomcat,無需部署WAR文件 3. 簡化Maven配置 4. 自動配置Spring 5. 提供生產就緒型功能,如日誌,健康檢查和外部配置 6. XML沒有要求配置 7. 很是容易和第三方框架集成起來; 缺點: 1,版本更新較快,可能出現較大變化; 2,由於約定大於配置,因此常常會出現一些很難解決的問題;

1,Springboot應用的基本結構:經過start.spring.io(網址)建立一個springboot應用: 2,spring-boot-starter-parent簡介: 1,包含了經常使用版本屬性; 要修改java編譯版本,能夠修改: <java.version>1.7</java.version> 2,包含了經常使用的dependenceManagement; 3,Springboot很是優秀的地方在於提供了很是多以spring-boot-starter-開頭的開箱即用的工具包,常見工具包有如下一些: spring-boot-starter:核心的工具包,提供了自動配置的支持,日誌和YAML配置支持; spring-boot-starter-activemq:針對快速集成ActiveMQ的工具包; spring-boot-starter-aop:提供了快速集成SpringAOP和AspectJ的工具包; spring-boot-starter-data-redis:提供了快速集成Redis和Jedis的工具包; spring-boot-starter-freemarker:提供了快速集成Freemarker的工具包; spring-boot-starter-mail:提供了快速集成郵件發送的工具包; spring-boot-starter-test:提供了對Springboot應用的測試工具包; spring-boot-starter-web:提供了對web開發的工具包,包括基於SpringMVC的RESTful應用開發,內置的tomcat服務器等; spring-boot-starter-actuator:提供了對生產環境中應用監控的工具包; spring-boot-starter-logging:提供了對日誌的工具包,默認使用Logback; 3,Springboot應用的熱部署: 除了使用JRebel來實現熱部署,還可使用Springboot提供的spring-boot-devtools包來完成Springboot應用熱部署; org.springframework.boot spring-boot-devtools true 1)原理: SpringBoot重啓是reload重啓,經過監控classpath的變化,若是classpath中的文件發生變化,即觸發重啓。springboot經過兩個classpath來完成reload,一個basic classloader中加載不變的類,一個restart classloader中加載classpath中的類,重啓的時候,restart classloader中的類丟棄並從新加載; 2)排除資源: spring.devtools.restart.exclude=static/,templates/ spring.devtools.restart.additional-exclude=public/* (處理默認配置排除以外的) spring.devtools.restart.enabled=false (禁用自動重啓)

@SpringBootApplication簡介: @SpringBootApplication由三個主要的標籤構成:@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan 1)@SpringBootConfiguration:本質就是一個@Configuration,表明這是spring容器的主配置類; 2)@EnableAutoConfiguration:開啓自動配置,Springboot使用這個標籤自動的把內置的符合條件的@Configuration類加載進入應用; 能夠查看spring-boot-autoconfigure包中的META-INF/spring.factories文件中的配置項(原理,由@EnableAutoConfiguration標籤引入的AutoConfigurationImportSelector類中,使用Spring的SpringFactoriesLoader類實現加載) 3)@ComponentScan:自動掃描;

SpringApplication簡介: 1,SpringApplication類提供了一個標準化的應用執行流程,並在這個執行流程中爲咱們提供了一些應用擴展點;但大部分狀況下,咱們只須要使用它就能夠了; 2,SpringBoot提供了一些擴展點,好比修改Banner: 1)建立一個banner.txt 2)設置banner,在配置文件中使用spring.main.banner-mode=off 3,能夠經過建立對象的方式來運行SpringApplication

2)經過builder完成:
複製代碼

4,參數的處理:在應用啓動過程當中,能夠經過啓動參數給應用傳遞一些額外的參數來控制應用的運行; 1,在main方法中能夠直接使用傳入的參數; 2,能夠任何類中直接經過@Autowired注入一個ApplicationArguments對象;

Springboot中的日誌

爲何要用日誌? 1.比起System.out.println,日誌框架能夠把日誌的輸出和代碼分離; 2.日誌框架能夠方便的定義日誌的輸出環境,控制檯,文件,數據庫; 3.日誌框架能夠方便的定義日誌的輸出格式和輸出級別;

Springboot的默認日誌使用: 1.Springboot默認已經開啓日誌;默認的日誌格式爲:時間 日誌級別 PID 線程名稱 日誌類 日誌說明 2.Springboot的日誌區別系統日誌和應用日誌; 3.Springboot推薦使用Logback做爲日誌框架(common-logging,java-logging,log4j,logback,slf4j)

Logback使用方法(推薦使用logback本身的配置文件) 1.springboot默認支持logback.xml或者logback-spring.xml,推薦使用logback-spring.xml,springboot會增長額外功能; 2.能夠經過logging.config=classpath:mylogback.xml指定本身的logback配置文件(不推薦); 3.一個典型的logback配置文件:

Logback使用介紹: 1,:Logback配置根元素 屬性包括: 1,scan: 當此屬性設置爲true時,配置文件若是發生改變,將會被從新加載,默認值爲true。 2,scanPeriod: 設置監測配置文件是否有修改的時間間隔,若是沒有給出時間單位,默認單位是毫秒。當scan爲true時,此屬性生效。默認的時間間隔爲1分鐘。 3,debug: 當此屬性設置爲true時,將打印出logback內部日誌信息,實時查看logback運行狀態。默認值爲false。 子元素: :上下文名字; :定義屬性,可使用${}在配置文件中使用;

2,:在logback中是用於具體記錄日誌的組件,能夠用來配置日誌記錄方式,日誌記錄格式等; 屬性包括: name:appender的名字,用於下面在配置日誌的時候指定; class:使用到的appender類;

常見的appender: 1,ch.qos.logback.core.ConsoleAppender:輸出到控制檯; 2,ch.qos.logback.core.FileAppender:輸出到文件; 3,ch.qos.logback.core.rolling.RollingFileAppender:輸出到文件,能夠配置滾動策略,當日志達到某個條件以後分文件記錄; 4,還有其餘的appender,好比寫到數據庫等;

元素的基本格式: ...

元素用來規定日誌的輸出格式,全部表達式都以%開始表示接下來是一個特殊標識符 常見標識符: 1,%logger{n}:輸出Logger對象類名,n表明長度; 2,%class{n}:輸出所在類名, 3,d{pattern}或者date{pattern}:輸出日誌日期,格式同java; 4,L/line:日誌所在行號; 5,m/msg:日誌內容; 6,method:所在方法名稱; 7,p/level:日誌級別; 8,thread:所在線程名稱;

常見的appender使用: 1)ConsoleAppender輸出到控制檯,子元素: :日誌格式化 :System.out(默認)或者System.err

圖片.png

2)FileAppender輸出到文件,子元素: file:被寫入的文件名,能夠是相對目錄,也能夠是絕對目錄,若是上級目錄不存在會自動建立,沒有默認值。 append:文件結尾,若是是 false,清空現存文件,默認是true。 encoder:對日誌進行格式化

圖片.png

3)RollingFileAppender輸出到文件,能夠設置文件滾動(分割)條件,子元素: append:若是是 true,日誌被追加到文件結尾,若是是 false,清空現存文件,默認是true。 rollingPolicy:滾動策略,涉及文件移動和重命名。 經常使用滾動策略: ch.qos.logback.core.rolling.TimeBasedRollingPolicy:按照時間控制來控制記錄文件; fileNamePattern:文件名稱格式,以%d{pattern}; maxHistory: 可選節點,控制保留的歸檔文件的最大數量,超出數量就刪除舊文件。(以文件最小時間爲準)

圖片.png

SizeAndTimeBasedRollingPolicy:按照時間和大小控制記錄文件; fileNamePattern:文件名稱格式,可使用%i來控制索引編號; maxFileSize:這是活動文件的大小,默認值是10MB maxHistory: 可選節點,控制保留的歸檔文件的最大數量,超出數量就刪除舊文件。(以文件最小時間爲準)

下面咱們來經過一個小Demo來講明 application.properties

db.username=username
db.password=password
db.url=url
springboot.randomlong=${random.long[1,100]}
複製代碼

MyDatasource.java

@Setter@Getter
public class MyDatasource {
private String username;
private String password;
private String url;
}
複製代碼

HelloController.java

@Controller
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
@Autowired
private MyDatasource datasource;
@RequestMapping("hello")
@ResponseBody
public String hello() {
	//error<warn<info<debug<trace
	logger.info("轉出成功");
	if (logger.isDebugEnabled()) {
		logger.debug("準備轉出10000");
	}
	if (logger.isTraceEnabled()) {
		logger.trace("鏈接數據庫");
		logger.trace("查詢帳戶餘額爲12000");
	}
	if (logger.isDebugEnabled()) {
		logger.debug("檢查轉出帳戶...");
		logger.debug("轉出檢查成功");
		logger.debug("執行轉出10000");
		logger.debug("轉出成功");
	}
	logger.info("轉入成功");
	System.out.println(datasource);
	return "hello world";
}
}
複製代碼

App.java

@SpringBootApplication
public class App {
@Bean
@ConfigurationProperties(prefix = "db")
public MyDatasource datasource() {
	return new MyDatasource();
}
public static void main(String[] args) {
	new SpringApplicationBuilder(App.class).bannerMode(Mode.OFF).build().run(args);
}
複製代碼

}


logback日誌的xml配置文件

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
	<encoder>
		<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
	</encoder>
	<target>System.out</target>
</appender>

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
	<encoder>
		<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
	</encoder>
	<file>springbootdemo.log</file>
	<append>true</append>
</appender>

<appender name="ROLLFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
	<encoder>
		<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
	</encoder>
	<append>true</append>
	<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
		<fileNamePattern>springboot.%d{yyyy-MM-dd}.log</fileNamePattern>
		<maxHistory>30</maxHistory>
	</rollingPolicy>
</appender>

<appender name="SIZEROLLFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
	<encoder>
		<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
	</encoder>
	<append>true</append>
	<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
		<fileNamePattern>springboot.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
		<maxFileSize>10MB</maxFileSize>
		<maxHistory>30</maxHistory>
	</rollingPolicy>
</appender>

<root level="DEBUG">
	<appender-ref ref="CONSOLE" />
	<appender-ref ref="SIZEROLLFILE" />
</root>
</configuration>
複製代碼

Springboot的WEB開發

Springmvc和freemarker的集成

添加依賴 引入spring-boot-starter-freemarker;

<dependency>
		<groupId>org.freemarker</groupId>
		<artifactId>freemarker</artifactId>
		<version>2.3.23</version>
	</dependency>
複製代碼

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>freemarker</display-name>
  <!-- SpringMVC前端控制器 -->
   <servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:application-web.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
  <!-- 編碼過濾器 -->
  <filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
	<param-name>encoding</param-name>
	<param-value>utf-8</param-value>
</init-param>
  </filter>
  <filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
  </filter-mapping>
  <welcome-file-list>
<welcome-file>index.do</welcome-file>
  </welcome-file-list>
</web-app>
複製代碼

application.xml

<!--開啓註解掃描 -->
<context:component-scan base-package="com.jd" />
複製代碼

application-web.xml

<import resource="classpath:application.xml" />
<!-- 支持springmvc的註解驅動 -->
<mvc:annotation-driven />
<!-- 配置一個freemarker的配置對象 -->
<bean
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
	<!-- 配置freemarker的文件編碼 -->
	<property name="defaultEncoding" value="UTF-8" />
	<!-- 配置freemarker尋找模板的路徑 -->
	<property name="templateLoaderPath" value="/WEB-INF/views/" />
</bean>
<!-- 配置一個針對於freemarker的viewresovler -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
	<!-- 配置邏輯視圖自動添加的後綴名 -->
	<property name="suffix" value=".ftl" />
	<!-- 配置視圖的輸出HTML的contentType -->
	<property name="contentType" value="text/html;charset=UTF-8" />
</bean>
複製代碼

FreemarkerController.java

@Controller
public class FreemarkerController {

@RequestMapping("hello")
public String hello(Model model){
	model.addAttribute("msg","hello 我是 freemarker");
	return "hello";
}
}
複製代碼

Springboot和freemarker的集成

添加依賴

<properties>
	<java.version>1.8</java.version>
</properties>
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-freemarker</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
	</dependency>
</dependencies>
<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>
複製代碼

建立模板

Snip20170910_27.png

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>${msg}</h1>
</body>
</html>
複製代碼

FreemarkerController.java

@Controller
public class FreemarkerController {

@RequestMapping("hello")
public String hello(Model model){
	model.addAttribute("msg","hello 我是 freemarker");
	return "hello";
}
}
複製代碼

App.java

//運行main
@SpringBootApplication
public class App {
public static void main(String[] args) {
	SpringApplication.run(App.class, args);
}
}
複製代碼

訪問網頁

Springboot對freemarker的配置: 1,spring.freemarker.enabled=true:是否開啓freemarker支持; 2,spring.freemarker.allow-request-override:是否容許request中的屬性覆蓋model中同名屬性;默認false; 3,spring.freemarker.allow-session-override:是否容許session中的屬性覆蓋model中同名屬性;默認false; 4,spring.freemarker.cache:是否支持模板緩存;默認false; 5,spring.freemarker.charset=UTF-8:模板編碼 6,spring.freemarker.content-type=text/html:模板contenttype; 7,spring.freemarker.expose-request-attributes:是否開啓request屬性expose,默認false; 8,spring.freemarker.expose-session-attributes:是否開啓session屬性expose,默認false; 9,spring.freemarker.expose-spring-macro-helpers:是否開啓spring的freemarker宏支持;默認爲false; 10,spring.freemarker.prefer-file-system-access:默認爲true,支持實時檢查模板修改; 11,spring.freemarker.prefix:加載模板時候的前綴; 12,spring.freemarker.settings.*:直接配置freemarker參數 13,spring.freemarker.suffix:模板文件後綴; 14,spring.freemarker.template-loader-path=classpath:/templates/:模板加載地址

通常狀況下咱們會把如下配置加入進去的 系統會自動讀取

application.properties

spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html;charset=UTF-8
spring.freemarker.expose-session-attributes=true
複製代碼

Springboot錯誤統一處理(@ControllerAdvice)

1).@ControllerAdvice 經過使用@ControllerAdvice定義統一的異常處理類,而不是在每一個Controller中逐個定義。@ExceptionHandler用來定義函數針對的異常類型。

GlobalExceptionHandler.java

@ControllerAdvice
public class GlobalExceptionHandler {
    //@ExceptionHandler(logicException.class)也能夠分狀況處理異常
@ExceptionHandler(Exception.class)
public String errorHandler(Model model, Exception e) {
	model.addAttribute("error", e.getMessage());
	//到模板找到err.ftl將錯誤信息顯示出來
	return "err";
    }
}
複製代碼

2)統一的異常頁面 1,SpringBoot默認狀況下,把全部錯誤都從新定位到/error這個處理路徑上,由BasicErrorController類完成處理; 2,SpringBoot提供了默認的替換錯誤頁面的路徑: 1,靜態錯誤頁面默認結構:(按照這個目錄結構放置錯誤頁面報錯時就會自動找到相應的界面) src/ resources/public/error/404.html src/ resources/public/error/ 403.html src/ resources/public/error/ 5xx.html

2,也可使用模板頁面: src/resources/templates/error/5xx.ftl 該路徑方式是經過ErrorMvcAutoConfiguration中的DefaultErrorViewResolver完成的;

Springboot集成DataSource和mybatis

集成DataSource方式1: 先加入依賴

<!-- druid -->
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid</artifactId>
		<version>1.0.14</version>
	</dependency>
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<scope>runtime</scope>
	</dependency>
複製代碼

DatasourceController .java

@Controller
public class DatasourceController {
@Autowired
private DataSource dataSource;

@RequestMapping("ds")
@ResponseBody
public String datasource() {
	return dataSource.getClass() + "  " + dataSource.toString();
}
}
複製代碼

運行main

@SpringBootApplication
public class App {
  //使用代碼的方式實現datasource
@Bean
public DataSource dataSource() {
	DruidDataSource dataSource = new DruidDataSource();
	dataSource.setUrl("jdbc:mysql:///p2p");
	dataSource.setUsername("root");
	dataSource.setPassword("123456");
	dataSource.setDriverClassName("com.mysql.jdbc.Driver");
	dataSource.setInitialSize(5);
	dataSource.setMinIdle(5);
	return dataSource;
}
public static void main(String[] args) {
	SpringApplication.run(App.class, args);
}
}
複製代碼

集成DataSource方式2:

使用配置文件的方式 application.properties

ds.username=root
ds.password=123456
ds.url=jdbc:mysql:///p2p
ds.driverClassName=com.mysql.jdbc.Driver
ds.initialSize=3
複製代碼

App.java

@Bean
@ConfigurationProperties(prefix = "ds")
public DataSource dataSource(Properties properties) throws Exception {
	return DruidDataSourceFactory.createDataSource(properties);
}

public static void main(String[] args) {
	SpringApplication.run(App.class, args);
}
複製代碼

集成DataSource方式3: 修改配置文件

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql:///p2p
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.initialSize=3
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
複製代碼

Springboot集成mybatis

mybatis集成: 使用mybatis-spring-boot-starter來完成mybatis集成;

1,引入依賴:

<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
複製代碼

2,正常完成mapper接口和mapper.xml 3,mybatis-spring-boot-starter提供瞭如下配置(具體參考MyBatisProperties對象):

mybatis.configLocation:mybatis的配置文件地址; mybatis.mapperLocations:映射文件地址; mybatis.typeAliasesPackage:別名掃描包;

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql:///p2p
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.initialSize=3
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.mapperLocation=classpath:com/jd/springboot/mybatis3/*Mapper.xml
mybatis.typeAliasesPackage=com.jd.springboot.mybatis3
複製代碼

4,使用@MapperScan標籤掃描mapper接口

@SpringBootApplication
@MapperScan(basePackages="com.jd.springboot.mybatis3")
 public class App {
public static void main(String[] args) {
	SpringApplication.run(App.class, args);
}
}
複製代碼

事務處理

1,使用代碼的方式:

1,直接開啓@EnableTransactionManagement註解;至關於在xml中配置tx:annotation-driven/

@SpringBootApplication
@MapperScan(basePackages="com.jd.springboot.demo.mybatis1.mapper")
@EnableTransactionManagement
public class App {
public static void main(String[] args) {
	SpringApplication.run(App.class, args);
}
}
複製代碼

若是在classpath中添加的是spring-boot-starter-jdbc,那麼springboot自動建立DataSourceTranscationManager;

@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
	return new DataSourceTransactionManager(dataSource);
}
複製代碼
若是開啓了@EnableTransactionManagement,只須要在service上面使用@Transactional便可;
2,使用xml配置

將事務相關配置抽取到XML中,使用importResource引入

1,引入aop

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-aop</artifactId>
	</dependency>
複製代碼

2,application-tx.xml

<tx:advice id="advice" transaction-manager="transactionManager">
	<tx:attributes>
		<tx:method name="list*" read-only="true" />
		<tx:method name="get*" read-only="true" />
		<tx:method name="query*" read-only="true" />
		<tx:method name="*" />
	</tx:attributes>
</tx:advice>

<aop:config>
	<aop:pointcut expression="execution(* com.jd.springboot.demo..service.*Service.*(..))"
		id="pointCut" />
	<aop:advisor advice-ref="advice" pointcut-ref="pointCut" />
</aop:config>
複製代碼

3,引入配置

@SpringBootApplication
@MapperScan(basePackages = "com.jd.springboot.demo.mybatis1.mapper")
@ImportResource(locations="classpath:application-tx.xml")
public class App {}
複製代碼
文件上傳

1,仍然使用MultipartFile完成上傳,Springboot是使用Servlet3中的Part對象完成上傳,不是使用的fileupload;

2,上傳相關配置: spring.http.multipart.enabled=true:是否容許處理上傳;

spring.http.multipart.maxFileSize=1MB:容許最大的單文件上傳大小,單位能夠是kb,mb;

spring.http.multipart.maxRequestSize=10MB:容許的最大請求大小;

3,也能夠經過建立一個MultipartConfigElement類型的bean對上傳進行配置:

@Bean
public MultipartConfigElement multipartConfigElement() {
	MultipartConfigFactory mcf = new MultipartConfigFactory();
	mcf.setMaxFileSize("1MB");
	mcf.setMaxRequestSize("10MB");
	return mcf.createMultipartConfig();
}
複製代碼

4,關於上傳文件的處理: 由於應用是打成jar包,因此通常會把上傳的文件放到其餘位置,並經過設置 spring.resources.static-locations 來完成資源位置映射。

spring.resources.static-locations=classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/, file:/Users/zhangshuai/devs/workspace/springboot-demo/upload/

#####SpringBoot總結 1.Maven中項目的繼承依賴包的管理 第1:在父項目中添加dependency,子項目不須要添加 第2:在父項目中添加dependencyManagement標籤,而後在添加dependency,子類對應的添加須要的dependency,但不須要寫版本號 2.項目分爲前臺和後臺兩個應用的好處 從安全性考慮,後臺是給公司管理人員用的,前臺是給用戶用的,訪問的URL地址是不同的,那這樣的話前臺用戶就不可能經過各類嘗試去訪問後臺管理系統了。 從性能方面考慮,項目分紅前臺和後臺把請求分發到不一樣的服務器中,下降單個服務器的壓力。 3.什麼是樂觀鎖?樂觀鎖能解決什麼問題? 樂觀鎖(Optimistic Lock): 顧名思義,就是很樂觀,每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據 sql 上的體現:加版本/時間戳控制語句 update set version = version+1 ... from .... where version = xxx 解決的問題:數據併發問題(丟失更新/髒讀)

4.事務是什麼?事務有哪些特性?事務用來幹什麼? (1)在數據庫中,所謂事務是指一組邏輯操做單元,使數據從一種狀態變換到另外一種狀態。 特性:

  1. 原子性(Atomicity)原子性是指事務是一個不可分割的工做單位,事務中的操做要麼都發生,要麼都不發生。
  2. 一致性(Consistency)事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態。(數據不被破壞)
  3. 隔離性(Isolation)事務的隔離性是指一個事務的執行不能被其餘事務干擾,即一個事務內部的操做及使用的數據對併發的其餘事務是隔離的,併發執行的各個事務之間不能互相干擾(事務空間)。
  4. 持久性(Durability)持久性是指一個事務一旦被提交,它對(3)數據庫中數據的改變就是永久性的,接下來的其餘操做和數據庫故障不該該對其有任何影響

爲確保數據庫中數據的一致性,數據的操縱應當是離散的成組的邏輯單元:當它所有完成時,數據的一致性能夠保持,而當這個單元中的一部分操做失敗,整個事務應所有視爲錯誤,全部從起始點之後的操做應所有回退到開始狀態。

5.Springboot應用的啓動原理? Springboot應用能夠在一個主啓動類中運行main方法或者打成jar包直接運行該jar包。 由於Springboot應用必定會在主啓動類貼上一個@SpringBootApplication註解,該註解有包含不少配置,至關於spring的主配置文件,而且springboot應用內嵌web服務器,在咱們啓動應用時,會先根據@SpringBootApplication註解的配置初始化spring容器,並運行在內嵌的web服務器上。

6.@Configuration標籤,@ComponentScan和@Bean標籤各自的做用; @Configuration:貼上該註解的類會被spring當成配置對象解析,能夠在該配置對象建立bean注入到spring容器(至關於以前咱們application.xml寫的配置) @ComponentScan:該註解與@Configuration:結合一塊兒使用,能夠掃描應用中的組件,好比貼了@Controller,@Service,@Component的類,並注入到spring容器中。此外,改註解能夠填寫掃描的包路徑,若是不寫的話就默認掃描貼了該註解的類所在的包及其子包。 @Bean:該註解結合@Configuration一塊兒使用,做用是把貼上該註解的方法返回的類注入到spring容器中。 7.@ConfigurationProperties標籤的做用; 該註解起到參數綁定的做用,能夠很是方便的把配置文件的配置信息綁定到Properties對象上,而且能夠控制到具體哪些前綴的配置信息須要綁定 8.日誌級別: error>warn>Info>debug>trace

點擊查看SpringBoot從入門到高級視頻教程

相關文章
相關標籤/搜索