SpringBoot從入門到高級(jí)

前言:學(xué)習(xí)SpringBoot不應(yīng)該直接就是開始使用SpringBoot,如果直接拿來用肯定會(huì)有很多人不是很明白特別剛開始入門的,當(dāng)然官網(wǎng)上也有快速上手的教程但是官網(wǎng)上跨度有點(diǎn)大,在這片文章中為主要是從以前沒使用SpringBoot之前我們?cè)趺醋龅囊约奥囊隨pringBoot,我希望通過自己的體會(huì)和認(rèn)識(shí)來幫助更多朋友來學(xué)習(xí)SpringBoot

目錄結(jié)構(gòu)

  • SpringJavaConfig
    • @Configuration和基礎(chǔ)的@Bean
    • @ComponentScan和測(cè)試
    • @Bean標(biāo)簽屬性詳解
    • @Import標(biāo)簽
    • XML和Annotation的混用
    • 其他常用標(biāo)簽(@PropertySource和@PropertySources,@Profile和@ActiveProfile)
  • 第一個(gè)HelloWorld
  • Springboot簡(jiǎn)介
  • Springboot基本使用
    • 應(yīng)用構(gòu)建
    • SpringApplication
    • 參數(shù)配置
  • 日志
    • 默認(rèn)日志
    • 外部日志框架LogBack
  • Springboot開發(fā)WEB應(yīng)用
    • 靜態(tài)資源
    • Freemarker集成
    • 錯(cuò)誤處理
    • mybatis集成
    • 事務(wù)處理
    • 文件上傳

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

(在這里我們先以最原始的方式來創(chuàng)建項(xiàng)目和測(cè)試)
創(chuàng)建一個(gè)Maven項(xiàng)目添加依賴和加入配置文件application.xml
SomeBean.java

public class SomeBean {}

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

這個(gè)是基于XML配置的方式
MyTest.java

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

上面是我們最簡(jiǎn)單的一個(gè)Spring Demo

下面通過標(biāo)簽來配置Spring
OtherBean.java

public class OtherBean {}

下面我們寫了一個(gè)方法返回一個(gè)SomeBean的對(duì)象我們要告訴Spring這個(gè)方法是Spring幫我們管理的bean通過@Bean標(biāo)簽

AppConfig .java

    // 作為Spring的主配置文件
    //@Configuration標(biāo)簽表示這個(gè)類可被Spring識(shí)別的配置對(duì)象的類,只有有這個(gè)標(biāo)記的標(biāo)簽的類才能使用@Bean標(biāo)簽作用于對(duì)應(yīng)的方法上面
    @Configuration
    public class AppConfig {
    //@Bean標(biāo)簽表示讓Spring幫我們管理bean
    @Bean
    public SomeBean someBean(){
        return new SomeBean();
    }
    @Bean
    public OtherBean otherBean(){
        return new  OtherBean();
    }
    }

不像上一個(gè)demo,這個(gè)是基于AnnotationConfigApplicationContext來配置的
MyTest.java

@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);
}

到這里我們就已經(jīng)學(xué)完了兩個(gè)重要的標(biāo)簽 @Configuration和@Bean,
@Configuration標(biāo)簽表示這個(gè)類可被Spring識(shí)別的配置對(duì)象的類,只有有這個(gè)標(biāo)記的標(biāo)簽的類才能使用
@Bean標(biāo)簽作用于對(duì)應(yīng)的方法上面
@Bean(destroyMethod = "destory", initMethod = "init")也可以通過這樣的寫法來配置bean的初始化方法和銷毀方法

@Component標(biāo)簽
@Component
public class SomeBean {}

@Component
public class OtherBean {}

//@Configuration標(biāo)簽表示這個(gè)類可被Spring識(shí)別的配置對(duì)象的類,這有有這個(gè)標(biāo)記的標(biāo)簽的類才能使用@Bean標(biāo)簽作用于對(duì)應(yīng)的方法上面
// @ComponentScan:開啟組件自動(dòng)掃描霎桅;默認(rèn)情況下帽揪,它會(huì)掃描當(dāng)前類所在的包及其子包中的所有標(biāo)簽對(duì)象加載到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:開啟組件自動(dòng)掃描;默認(rèn)情況下,它會(huì)掃描當(dāng)前類所在的包及其子包中的所有標(biāo)簽對(duì)象加載到Spring容器

對(duì)象的關(guān)系引用

在someBean里依賴一個(gè)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 {
//第一種方式(對(duì)象的注入)
@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來關(guān)閉容器

@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標(biāo)簽
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這個(gè)類因?yàn)榇蛏螥Configuration標(biāo)簽所以是主配置文件,他需要連接著兩個(gè)類ConfigDataSource.class,ConfigRedis.class 只需要使用@Import 標(biāo)簽就可以表示導(dǎo)入類

@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標(biāo)簽 在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標(biāo)簽來在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標(biāo)簽來導(dǎo)入資源

引入外部的.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引入多個(gè)外部資源文件

@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引入多個(gè)外部資源文件

@PropertySource("classpath:com/jd/properties/db.properties")
public class AppConfig {
 //Environment代表spring的環(huán)境,在環(huán)境里面只有兩種東西: 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;
}

//生產(chǎn)環(huán)境的配置對(duì)象
@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);
}
}

//針對(duì)開發(fā)環(huán)境的配置
@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);
}
}

到這里我們把需要回顧和拓展的知識(shí)都有一定加深下面我們開始正式學(xué)習(xí)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.創(chuàng)建一個(gè)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.運(yùn)行 main方法

. ____ _ __ _ _
/\ / ' __ _ () __ __ _ \ \ \
( ( )_
_ | '_ | '| | ' / ` | \ \ \
\/ )| |)| | | | | || (| | ) ) ) )
' |____| .
|| ||| |_, | / / / /
=========|
|==============|/=////
:: Spring Boot :: (v1.5.6.RELEASE)

分析:
1辜王,繼承spring-boot-starter-parent军拟,引入基本的依賴管理配置;
2誓禁,引入spring-boot-starter-web懈息,自動(dòng)引入了springweb相關(guān)的包;
3摹恰,@SpringBootApplication:這個(gè)注解告訴springboot自動(dòng)的去完成相關(guān)配置辫继,包括基礎(chǔ)類的加載,bean的掃描等等俗慈,這個(gè)后面詳細(xì)介紹姑宽;簡(jiǎn)單理解為這個(gè)標(biāo)簽為我們的應(yīng)用配置完成了很多基本功能;
4闺阱,SpringApplication.run:這個(gè)是springboot為我們提供的最大的區(qū)別炮车,在于springboot不再是一個(gè)web應(yīng)用,需要我們自己去打包酣溃,部署瘦穆,啟動(dòng)tomcat,springboot默認(rèn)把tomcat打包到應(yīng)用中赊豌,我們可以以正常的運(yùn)行jar的方式來運(yùn)行springboot應(yīng)用扛或;

應(yīng)用獨(dú)立運(yùn)行:
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運(yùn)行悲伶;注意,一定要引入spring-boot-maven-plugin之后運(yùn)行package打包才能正常運(yùn)行住涉;

3麸锉,直接使用maven插件:spring-boot:run運(yùn)行;

Springboot的優(yōu)缺點(diǎn)
1. 創(chuàng)建獨(dú)立的Spring應(yīng)用程序
2. 嵌入的Tomcat舆声,無需部署WAR文件
3. 簡(jiǎn)化Maven配置
4. 自動(dòng)配置Spring
5. 提供生產(chǎn)就緒型功能淮椰,如日志,健康檢查和外部配置
6. XML沒有要求配置
7. 非常容易和第三方框架集成起來纳寂;
缺點(diǎn):
1主穗,版本更新較快,可能出現(xiàn)較大變化毙芜;
2忽媒,因?yàn)榧s定大于配置,所以經(jīng)常會(huì)出現(xiàn)一些很難解決的問題腋粥;

1晦雨,Springboot應(yīng)用的基本結(jié)構(gòu):通過start.spring.io(網(wǎng)址)創(chuàng)建一個(gè)springboot應(yīng)用:
2,spring-boot-starter-parent簡(jiǎn)介:
1隘冲,包含了常用版本屬性闹瞧;
要修改java編譯版本,可以修改: <properties> <java.version>1.7</java.version> </properties>
2展辞,包含了常用的dependenceManagement;
3奥邮,Springboot非常優(yōu)秀的地方在于提供了非常多以spring-boot-starter-開頭的開箱即用的工具包,常見工具包有以下一些:
spring-boot-starter:核心的工具包罗珍,提供了自動(dòng)配置的支持洽腺,日志和YAML配置支持;
spring-boot-starter-activemq:針對(duì)快速集成ActiveMQ的工具包覆旱;
spring-boot-starter-aop:提供了快速集成SpringAOP和AspectJ的工具包蘸朋;
spring-boot-starter-data-redis:提供了快速集成Redis和Jedis的工具包;
spring-boot-starter-freemarker:提供了快速集成Freemarker的工具包扣唱;
spring-boot-starter-mail:提供了快速集成郵件發(fā)送的工具包藕坯;
spring-boot-starter-test:提供了對(duì)Springboot應(yīng)用的測(cè)試工具包;
spring-boot-starter-web:提供了對(duì)web開發(fā)的工具包噪沙,包括基于SpringMVC的RESTful應(yīng)用開發(fā)炼彪,內(nèi)置的tomcat服務(wù)器等;
spring-boot-starter-actuator:提供了對(duì)生產(chǎn)環(huán)境中應(yīng)用監(jiān)控的工具包曲聂;
spring-boot-starter-logging:提供了對(duì)日志的工具包霹购,默認(rèn)使用Logback;
3朋腋,Springboot應(yīng)用的熱部署:
除了使用JRebel來實(shí)現(xiàn)熱部署齐疙,還可以使用Springboot提供的spring-boot-devtools包來完成Springboot應(yīng)用熱部署;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
1)原理:
SpringBoot重啟是reload重啟旭咽,通過監(jiān)控classpath的變化贞奋,如果classpath中的文件發(fā)生變化,即觸發(fā)重啟穷绵。springboot通過兩個(gè)classpath來完成reload轿塔,一個(gè)basic classloader中加載不變的類,一個(gè)restart classloader中加載classpath中的類仲墨,重啟的時(shí)候勾缭,restart classloader中的類丟棄并重新加載;
2)排除資源:
spring.devtools.restart.exclude=static/
,templates/*
spring.devtools.restart.additional-exclude=public/** (處理默認(rèn)配置排除之外的)
spring.devtools.restart.enabled=false (禁用自動(dòng)重啟)

@SpringBootApplication簡(jiǎn)介:
@SpringBootApplication由三個(gè)主要的標(biāo)簽構(gòu)成:@SpringBootConfiguration目养,@EnableAutoConfiguration俩由,@ComponentScan
1)@SpringBootConfiguration:本質(zhì)就是一個(gè)@Configuration,代表這是spring容器的主配置類癌蚁;
2)@EnableAutoConfiguration:開啟自動(dòng)配置幻梯,Springboot使用這個(gè)標(biāo)簽自動(dòng)的把內(nèi)置的符合條件的@Configuration類加載進(jìn)入應(yīng)用;
可以查看spring-boot-autoconfigure包中的META-INF/spring.factories文件中的配置項(xiàng)(原理努释,由@EnableAutoConfiguration標(biāo)簽引入的AutoConfigurationImportSelector類中碘梢,使用Spring的SpringFactoriesLoader類實(shí)現(xiàn)加載)
3)@ComponentScan:自動(dòng)掃描;

SpringApplication簡(jiǎn)介:
1伐蒂,SpringApplication類提供了一個(gè)標(biāo)準(zhǔn)化的應(yīng)用執(zhí)行流程煞躬,并在這個(gè)執(zhí)行流程中為我們提供了一些應(yīng)用擴(kuò)展點(diǎn);但大部分情況下逸邦,我們只需要使用它就可以了汰翠;
2,SpringBoot提供了一些擴(kuò)展點(diǎn)昭雌,比如修改Banner:
1)創(chuàng)建一個(gè)banner.txt
2)設(shè)置banner复唤,在配置文件中使用spring.main.banner-mode=off
3,可以通過創(chuàng)建對(duì)象的方式來運(yùn)行SpringApplication

 2)通過builder完成:

4烛卧,參數(shù)的處理:在應(yīng)用啟動(dòng)過程中佛纫,可以通過啟動(dòng)參數(shù)給應(yīng)用傳遞一些額外的參數(shù)來控制應(yīng)用的運(yùn)行;
1总放,在main方法中可以直接使用傳入的參數(shù)呈宇;
2廊蜒,可以任何類中直接通過@Autowired注入一個(gè)ApplicationArguments對(duì)象胆建;

Springboot中的日志

為什么要用日志?
1.比起System.out.println撼玄,日志框架可以把日志的輸出和代碼分離炬搭;
2.日志框架可以方便的定義日志的輸出環(huán)境蜈漓,控制臺(tái)穆桂,文件,數(shù)據(jù)庫融虽;
3.日志框架可以方便的定義日志的輸出格式和輸出級(jí)別享完;

Springboot的默認(rèn)日志使用:
1.Springboot默認(rèn)已經(jīng)開啟日志;默認(rèn)的日志格式為:時(shí)間 日志級(jí)別 PID 線程名稱 日志類 日志說明
2.Springboot的日志區(qū)別系統(tǒng)日志和應(yīng)用日志有额;
3.Springboot推薦使用Logback作為日志框架(common-logging般又,java-logging,log4j巍佑,logback茴迁,slf4j)

Logback使用方法(推薦使用logback自己的配置文件)
1.springboot默認(rèn)支持logback.xml或者logback-spring.xml,推薦使用logback-spring.xml萤衰,springboot會(huì)增加額外功能堕义;
2.可以通過logging.config=classpath:mylogback.xml指定自己的logback配置文件(不推薦);
3.一個(gè)典型的logback配置文件:


Logback使用介紹:
1腻菇,<configuration>:Logback配置根元素
屬性包括:
1,scan: 當(dāng)此屬性設(shè)置為true時(shí)胳螟,配置文件如果發(fā)生改變,將會(huì)被重新加載筹吐,默認(rèn)值為true糖耸。
2,scanPeriod: 設(shè)置監(jiān)測(cè)配置文件是否有修改的時(shí)間間隔,如果沒有給出時(shí)間單位丘薛,默認(rèn)單位是毫秒嘉竟。當(dāng)scan為true時(shí),此屬性生效洋侨。默認(rèn)的時(shí)間間隔為1分鐘舍扰。
3,debug: 當(dāng)此屬性設(shè)置為true時(shí),將打印出logback內(nèi)部日志信息希坚,實(shí)時(shí)查看logback運(yùn)行狀態(tài)边苹。默認(rèn)值為false。
子元素:
<contextName>:上下文名字裁僧;
<property>:定義屬性个束,可以使用${}在配置文件中使用;

2聊疲,<appender>:在logback中是用于具體記錄日志的組件茬底,可以用來配置日志記錄方式,日志記錄格式等获洲;
屬性包括:
name:appender的名字阱表,用于下面在配置日志的時(shí)候指定;
class:使用到的appender類;

常見的appender:
1最爬,ch.qos.logback.core.ConsoleAppender:輸出到控制臺(tái)涉馁;
2,ch.qos.logback.core.FileAppender:輸出到文件烂叔;
3谨胞,ch.qos.logback.core.rolling.RollingFileAppender:輸出到文件固歪,可以配置滾動(dòng)策略蒜鸡,當(dāng)日志達(dá)到某個(gè)條件之后分文件記錄;
4牢裳,還有其他的appender逢防,比如寫到數(shù)據(jù)庫等;

<appender>元素的基本格式:
<appender name="" class="">
<encoder>
<pattern>...</pattern>
</encoder>
<otherconfig></otherconfig>
</appender>

<encoder>元素用來規(guī)定日志的輸出格式蒲讯,所有表達(dá)式都以%開始表示接下來是一個(gè)特殊標(biāo)識(shí)符
常見標(biāo)識(shí)符:
1忘朝,%logger{n}:輸出Logger對(duì)象類名,n代表長(zhǎng)度判帮;
2局嘁,%class{n}:輸出所在類名,
3晦墙,d{pattern}或者date{pattern}:輸出日志日期悦昵,格式同java;
4晌畅,L/line:日志所在行號(hào)但指;
5,m/msg:日志內(nèi)容抗楔;
6棋凳,method:所在方法名稱;
7连躏,p/level:日志級(jí)別剩岳;
8,thread:所在線程名稱入热;

常見的appender使用:
1)ConsoleAppender輸出到控制臺(tái)拍棕,子元素:
<encoder>:日志格式化
<target>:System.out(默認(rèn))或者System.err

圖片.png

2)FileAppender輸出到文件,子元素:
file:被寫入的文件名才顿,可以是相對(duì)目錄莫湘,也可以是絕對(duì)目錄,如果上級(jí)目錄不存在會(huì)自動(dòng)創(chuàng)建郑气,沒有默認(rèn)值幅垮。
append:文件結(jié)尾,如果是 false尾组,清空現(xiàn)存文件忙芒,默認(rèn)是true示弓。
encoder:對(duì)日志進(jìn)行格式化

圖片.png

3)RollingFileAppender輸出到文件,可以設(shè)置文件滾動(dòng)(分割)條件呵萨,子元素:
append:如果是 true奏属,日志被追加到文件結(jié)尾,如果是 false潮峦,清空現(xiàn)存文件囱皿,默認(rèn)是true。
rollingPolicy:滾動(dòng)策略忱嘹,涉及文件移動(dòng)和重命名嘱腥。
常用滾動(dòng)策略:
ch.qos.logback.core.rolling.TimeBasedRollingPolicy:按照時(shí)間控制來控制記錄文件;
fileNamePattern:文件名稱格式拘悦,以%d{pattern}齿兔;
maxHistory:
可選節(jié)點(diǎn),控制保留的歸檔文件的最大數(shù)量础米,超出數(shù)量就刪除舊文件分苇。(以文件最小時(shí)間為準(zhǔn))

圖片.png

SizeAndTimeBasedRollingPolicy:按照時(shí)間和大小控制記錄文件;
fileNamePattern:文件名稱格式屁桑,可以使用%i來控制索引編號(hào)医寿;
maxFileSize:這是活動(dòng)文件的大小,默認(rèn)值是10MB
maxHistory:
可選節(jié)點(diǎn)掏颊,控制保留的歸檔文件的最大數(shù)量糟红,超出數(shù)量就刪除舊文件。(以文件最小時(shí)間為準(zhǔn))

下面我們來通過一個(gè)小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("轉(zhuǎn)出成功");
    if (logger.isDebugEnabled()) {
        logger.debug("準(zhǔn)備轉(zhuǎn)出10000");
    }
    if (logger.isTraceEnabled()) {
        logger.trace("連接數(shù)據(jù)庫");
        logger.trace("查詢賬戶余額為12000");
    }
    if (logger.isDebugEnabled()) {
        logger.debug("檢查轉(zhuǎn)出賬戶...");
        logger.debug("轉(zhuǎn)出檢查成功");
        logger.debug("執(zhí)行轉(zhuǎn)出10000");
        logger.debug("轉(zhuǎn)出成功");
    }
    logger.info("轉(zhuǎn)入成功");
    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開發(fā)

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的注解驅(qū)動(dòng) -->
<mvc:annotation-driven />
<!-- 配置一個(gè)freemarker的配置對(duì)象 -->
<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>
<!-- 配置一個(gè)針對(duì)于freemarker的viewresovler -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <!-- 配置邏輯視圖自動(dòng)添加的后綴名 -->
    <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>

創(chuàng)建模板

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

//運(yùn)行main
@SpringBootApplication
public class App {
public static void main(String[] args) {
    SpringApplication.run(App.class, args);
}
}

訪問網(wǎng)頁

Springboot對(duì)freemarker的配置:
1乌叶,spring.freemarker.enabled=true:是否開啟freemarker支持盆偿;
2,spring.freemarker.allow-request-override:是否允許request中的屬性覆蓋model中同名屬性准浴;默認(rèn)false事扭;
3,spring.freemarker.allow-session-override:是否允許session中的屬性覆蓋model中同名屬性乐横;默認(rèn)false求橄;
4,spring.freemarker.cache:是否支持模板緩存葡公;默認(rèn)false罐农;
5,spring.freemarker.charset=UTF-8:模板編碼
6催什,spring.freemarker.content-type=text/html:模板contenttype涵亏;
7,spring.freemarker.expose-request-attributes:是否開啟request屬性expose,默認(rèn)false气筋;
8拆内,spring.freemarker.expose-session-attributes:是否開啟session屬性expose,默認(rèn)false宠默;
9麸恍,spring.freemarker.expose-spring-macro-helpers:是否開啟spring的freemarker宏支持;默認(rèn)為false搀矫;
10抹沪,spring.freemarker.prefer-file-system-access:默認(rèn)為true,支持實(shí)時(shí)檢查模板修改艾君;
11采够,spring.freemarker.prefix:加載模板時(shí)候的前綴肄方;
12冰垄,spring.freemarker.settings.*:直接配置freemarker參數(shù)
13,spring.freemarker.suffix:模板文件后綴权她;
14虹茶,spring.freemarker.template-loader-path=classpath:/templates/:模板加載地址

一般情況下我們會(huì)把以下配置加入進(jìn)去的 系統(tǒng)會(huì)自動(dòng)讀取

application.properties

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

Springboot錯(cuò)誤統(tǒng)一處理(@ControllerAdvice)

1).@ControllerAdvice
通過使用@ControllerAdvice定義統(tǒng)一的異常處理類,而不是在每個(gè)Controller中逐個(gè)定義隅要。@ExceptionHandler用來定義函數(shù)針對(duì)的異常類型蝴罪。


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將錯(cuò)誤信息顯示出來
    return "err";
    }
}

2)統(tǒng)一的異常頁面
1,SpringBoot默認(rèn)情況下,把所有錯(cuò)誤都重新定位到/error這個(gè)處理路徑上步清,由BasicErrorController類完成處理要门;
2,SpringBoot提供了默認(rèn)的替換錯(cuò)誤頁面的路徑:
1廓啊,靜態(tài)錯(cuò)誤頁面默認(rèn)結(jié)構(gòu):(按照這個(gè)目錄結(jié)構(gòu)放置錯(cuò)誤頁面報(bào)錯(cuò)時(shí)就會(huì)自動(dòng)找到相應(yīng)的界面)
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();
}
}

運(yùn)行main

@SpringBootApplication
public class App {
  //使用代碼的方式實(shí)現(xiàn)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對(duì)象):

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標(biāo)簽掃描mapper接口

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

事務(wù)處理

1,使用代碼的方式:

1翩隧,直接開啟@EnableTransactionManagement注解樊展;相當(dāng)于在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自動(dòng)創(chuàng)建DataSourceTranscationManager;

@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}
如果開啟了@EnableTransactionManagement滚局,只需要在service上面使用@Transactional即可居暖;
2,使用xml配置

將事務(wù)相關(guān)配置抽取到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對(duì)象完成上傳最住,不是使用的fileupload钞澳;

2,上傳相關(guān)配置:
spring.http.multipart.enabled=true:是否允許處理上傳涨缚;

spring.http.multipart.maxFileSize=1MB:允許最大的單文件上傳大小轧粟,單位可以是kb,mb脓魏;

spring.http.multipart.maxRequestSize=10MB:允許的最大請(qǐng)求大欣家鳌;

3茂翔,也可以通過創(chuàng)建一個(gè)MultipartConfigElement類型的bean對(duì)上傳進(jìn)行配置:

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

4混蔼,關(guān)于上傳文件的處理:
因?yàn)閼?yīng)用是打成jar包,所以一般會(huì)把上傳的文件放到其他位置珊燎,并通過設(shè)置
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總結(jié)

1.Maven中項(xiàng)目的繼承依賴包的管理
第1:在父項(xiàng)目中添加dependency,子項(xiàng)目不需要添加
第2:在父項(xiàng)目中添加dependencyManagement標(biāo)簽,然后在添加dependency悔政,子類對(duì)應(yīng)的添加需要的dependency晚吞,但不需要寫版本號(hào)
2.項(xiàng)目分為前臺(tái)和后臺(tái)兩個(gè)應(yīng)用的好處
從安全性考慮,后臺(tái)是給公司管理人員用的卓箫,前臺(tái)是給用戶用的载矿,訪問的URL地址是不一樣的,那這樣的話前臺(tái)用戶就不可能通過各種嘗試去訪問后臺(tái)管理系統(tǒng)了烹卒。
從性能方面考慮闷盔,項(xiàng)目分成前臺(tái)和后臺(tái)把請(qǐng)求分發(fā)到不同的服務(wù)器中,降低單個(gè)服務(wù)器的壓力旅急。
3.什么是樂觀鎖逢勾?樂觀鎖能解決什么問題?
樂觀鎖(Optimistic Lock): 顧名思義藐吮,就是很樂觀溺拱,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會(huì)修改逃贝,所以不會(huì)上鎖,但是在更新的時(shí)候會(huì)判斷一下在此期間別人有沒有去更新這個(gè)數(shù)據(jù)
sql 上的體現(xiàn):加版本/時(shí)間戳控制語句
update set version = version+1 ... from .... where version = xxx
解決的問題:數(shù)據(jù)并發(fā)問題(丟失更新/臟讀)

4.事務(wù)是什么迫摔?事務(wù)有哪些特性沐扳?事務(wù)用來干什么?
(1)在數(shù)據(jù)庫中,所謂事務(wù)是指一組邏輯操作單元,使數(shù)據(jù)從一種狀態(tài)變換到另一種狀態(tài)句占。
特性:

  1. 原子性(Atomicity)原子性是指事務(wù)是一個(gè)不可分割的工作單位沪摄,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生纱烘。
  2. 一致性(Consistency)事務(wù)必須使數(shù)據(jù)庫從一個(gè)一致性狀態(tài)變換到另外一個(gè)一致性狀態(tài)杨拐。(數(shù)據(jù)不被破壞)
  3. 隔離性(Isolation)事務(wù)的隔離性是指一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾,即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)并發(fā)的其他事務(wù)是隔離的擂啥,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾(事務(wù)空間)哄陶。
  4. 持久性(Durability)持久性是指一個(gè)事務(wù)一旦被提交,它對(duì)(3)數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的哺壶,接下來的其他操作和數(shù)據(jù)庫故障不應(yīng)該對(duì)其有任何影響

為確保數(shù)據(jù)庫中數(shù)據(jù)的一致性,數(shù)據(jù)的操縱應(yīng)當(dāng)是離散的成組的邏輯單元:當(dāng)它全部完成時(shí),數(shù)據(jù)的一致性可以保持,而當(dāng)這個(gè)單元中的一部分操作失敗,整個(gè)事務(wù)應(yīng)全部視為錯(cuò)誤,所有從起始點(diǎn)以后的操作應(yīng)全部回退到開始狀態(tài)屋吨。

5.Springboot應(yīng)用的啟動(dòng)原理?
Springboot應(yīng)用可以在一個(gè)主啟動(dòng)類中運(yùn)行main方法或者打成jar包直接運(yùn)行該jar包变骡。
因?yàn)镾pringboot應(yīng)用一定會(huì)在主啟動(dòng)類貼上一個(gè)@SpringBootApplication注解离赫,該注解有包含很多配置,相當(dāng)于spring的主配置文件塌碌,并且springboot應(yīng)用內(nèi)嵌web服務(wù)器,在我們啟動(dòng)應(yīng)用時(shí)旬盯,會(huì)先根據(jù)@SpringBootApplication注解的配置初始化spring容器台妆,并運(yùn)行在內(nèi)嵌的web服務(wù)器上。

6.@Configuration標(biāo)簽胖翰,@ComponentScan和@Bean標(biāo)簽各自的作用接剩;
@Configuration:貼上該注解的類會(huì)被spring當(dāng)成配置對(duì)象解析,可以在該配置對(duì)象創(chuàng)建bean注入到spring容器(相當(dāng)于之前我們application.xml寫的配置)
@ComponentScan:該注解與@Configuration:結(jié)合一起使用萨咳,可以掃描應(yīng)用中的組件懊缺,比如貼了@Controller,@Service培他,@Component的類鹃两,并注入到spring容器中。此外舀凛,改注解可以填寫掃描的包路徑俊扳,如果不寫的話就默認(rèn)掃描貼了該注解的類所在的包及其子包。
@Bean:該注解結(jié)合@Configuration一起使用猛遍,作用是把貼上該注解的方法返回的類注入到spring容器中馋记。
7.@ConfigurationProperties標(biāo)簽的作用号坡;
該注解起到參數(shù)綁定的作用,可以非常方便的把配置文件的配置信息綁定到Properties對(duì)象上梯醒,并且可以控制到具體哪些前綴的配置信息需要綁定
8.日志級(jí)別:
error>warn>Info>debug>trace

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宽堆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子茸习,更是在濱河造成了極大的恐慌日麸,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逮光,死亡現(xiàn)場(chǎng)離奇詭異代箭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)涕刚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門嗡综,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人杜漠,你說我怎么就攤上這事极景。” “怎么了驾茴?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵盼樟,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我锈至,道長(zhǎng)晨缴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任峡捡,我火速辦了婚禮击碗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘们拙。我一直安慰自己稍途,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布砚婆。 她就那樣靜靜地躺著械拍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪装盯。 梳的紋絲不亂的頭發(fā)上坷虑,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音验夯,去河邊找鬼猖吴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛挥转,可吹牛的內(nèi)容都是我干的海蔽。 我是一名探鬼主播共屈,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼党窜!你這毒婦竟也來了拗引?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤幌衣,失蹤者是張志新(化名)和其女友劉穎矾削,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豁护,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哼凯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了楚里。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片断部。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖班缎,靈堂內(nèi)的尸體忽然破棺而出蝴光,到底是詐尸還是另有隱情,我是刑警寧澤达址,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布蔑祟,位于F島的核電站,受9級(jí)特大地震影響沉唠,放射性物質(zhì)發(fā)生泄漏疆虚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一右冻、第九天 我趴在偏房一處隱蔽的房頂上張望装蓬。 院中可真熱鬧,春花似錦纱扭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鄙币,卻和暖如春肃叶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背十嘿。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工因惭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人绩衷。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓蹦魔,卻偏偏與公主長(zhǎng)得像激率,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子勿决,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容