Spring boot簡介
Spring Boot是伴隨著Spring4.0產(chǎn)生的,是由Pivotal團隊提供的全新框架,其設(shè)計目的是用來簡化新Spring應用的初始搭建以及開發(fā)過程。該框架使用了特定的方式進行配置,從而使開發(fā)人員不再需要定義樣板化的配置。通過這種方式,Boot致力于在蓬勃發(fā)展的快速應用開發(fā)領(lǐng)域(rapid application development)成為領(lǐng)導者。
Spring Boot讓我們的Spring應用變得更輕量化。比如:你可以僅僅依靠一個Java類來運行Spring引用。你也可以打包你的應用為jar并通過使用java –jar來運行你的Spring Web應用。
- Spring Boot的主要優(yōu)點:
為所有Spring開發(fā)者更快的入門
開箱即用,提供各種默認配置來簡化項目配置
內(nèi)嵌式容器簡化web項目
沒有冗余代碼生成和xml配置的要求
盡可能的根據(jù)項目依賴來自動配置Spring框架。
提供可以直接在生產(chǎn)環(huán)境中使用的功能,如性能指標,應用信息和應用健康檢查。
Spring Boot的缺點
依賴太多,隨便的一個Spring Boot應用都有好幾十M
缺少服務(wù)的注冊和發(fā)現(xiàn)等解決方案,可以結(jié)合springcloud的組件使用。
缺少監(jiān)控集成方案、安全管理方案(有但簡單,滿足不了生產(chǎn)的指標)
簡單demo
使用maven構(gòu)建項目,官方現(xiàn)在穩(wěn)定版本是1.5.4,第一個入門demo不是web項目,pom依賴如下:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
實體User類:
package com.zhihao.miao.bean;
import org.springframework.stereotype.Component;
@Component
public class User {
private String username = "zhihao.miao";
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}
}
配置類:
package com.zhihao.miao.bean;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import java.util.HashMap;
import java.util.Map;
@SpringBootConfiguration
public class ConfigurationTest {
@Bean
public Map createMap(){
Map map = new HashMap();
map.put("username","zhihao.miao");
map.put("age",27);
return map;
}
}
入口類Application:
package com.zhihao.miao;
import com.zhihao.miao.bean.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import java.util.Map;
@SpringBootApplication
public class Application {
@Bean
public Runnable createRunnable(){
return () -> System.out.println("spring boot is running");
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
context.getBean(Runnable.class).run();
System.out.println(context.getBean(User.class));
Map map = (Map) context.getBean("createMap");
int age = (int) map.get("age");
System.out.println("age=="+age);
}
}
項目結(jié)構(gòu)目錄

啟動程序,以main方法啟動:

打印出正確的結(jié)果。
spring boot is running
User{username='zhihao.miao', age=0}
age==27
來分析一下流程,為何Runnable類,User,Map會納入spring容器。
首先我們分析的就是入口類Application的啟動注解@SpringBootApplication,進入源碼:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
....
發(fā)現(xiàn)@SpringBootApplication是一個復合注解,包括@ComponentScan,和@SpringBootConfiguration,@EnableAutoConfiguration。
@SpringBootConfiguration繼承自@Configuration,二者功能也一致,標注當前類是配置類,并會將當前類內(nèi)聲明的一個或多個以@Bean注解標記的方法的實例納入到srping容器中,并且實例名就是方法名。
-
@EnableAutoConfiguration的作用啟動自動的配置,@EnableAutoConfiguration注解的意思就是Springboot根據(jù)你添加的jar包來配置你項目的默認配置,比如根據(jù)spring-boot-starter-web,來判斷你的項目是否需要添加了webmvc和tomcat,就會自動的幫你配置web項目中所需要的默認配置。在下面博客會具體分析這個注解,快速入門的demo實際沒有用到該注解。 -
@ComponentScan,掃描當前包及其子包下被@Component,@Controller,@Service,@Repository注解標記的類并納入到spring容器中進行管理。是以前的<context:component-scan>(以前使用在xml中使用的標簽,用來掃描包配置的平行支持)。所以本demo中的User為何會被spring容器管理。
根據(jù)上面的理解,上面的入口類Application,我們可以使用:
package com.zhihao.miao;
import com.zhihao.miao.bean.User;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import java.util.Map;
@ComponentScan
public class Application {
@Bean
public Runnable createRunnable(){
return () -> System.out.println("spring boot is running");
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
context.getBean(Runnable.class).run();
System.out.println(context.getBean(User.class));
Map map = (Map) context.getBean("createMap");
int age = (int) map.get("age");
System.out.println("age=="+age);
}
}
使用@ComponentScan注解代替@SpringBootApplication注解,也可以正常運行程序。原因是@SpringBootApplication中包含@ComponentScan,并且springboot會將入口類看作是一個@SpringBootConfiguration標記的配置類,所以定義在入口類Application中的Runnable也可以納入到容器管理。
SpringBootApplication參數(shù)詳解

- Class<?>[] exclude() default {}:
根據(jù)class來排除,排除特定的類加入spring容器,傳入?yún)?shù)value類型是class類型。
- String[] excludeName() default {}:
根據(jù)class name來排除,排除特定的類加入spring容器,傳入?yún)?shù)value類型是class的全類名字符串數(shù)組。 - String[] scanBasePackages() default {}:
指定掃描包,參數(shù)是包名的字符串數(shù)組。 - Class<?>[] scanBasePackageClasses() default {}:
掃描特定的包,參數(shù)類似是Class類型數(shù)組。
看一個demo學會使用這些參數(shù)配置
在包下com.zhihao.miao.springboot定義一個啟動應用類(加上@SpringBootApplication注解)
package com.zhihao.miao.springboot;
import com.zhihao.miao.beans.Cat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
Cat cat = context.getBean(Cat.class);
System.out.println(cat);
}
}
在com.zhihao.miao.beans包下定義一個實體類,并且想將其納入到spring容器中,
public class Cat {
}
package com.zhihao.miao.beans;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
@Bean
public Cat cat(){
return new Cat();
}
}
啟動啟動類,打印結(jié)果如下:

說明Cat類并沒有納入到spring容器中,這個結(jié)果也如我們所想,因為@SpringBootApplication只會掃描@SpringBootApplication注解標記類包下及其子包的類(特定注解標記,比如說@Controller,@Service,@Component,@Configuration和@Bean注解等等)納入到spring容器,很顯然MyConfig不在@SpringBootApplication注解標記類相同包下及其子包的類,所以需要我們?nèi)ヅ渲靡幌聮甙窂健?/p>
修改啟動類,@SpringBootApplication(scanBasePackages = "com.zhihao.miao"),指定掃描路徑:
package com.zhihao.miao.springboot;
import com.zhihao.miao.beans.Cat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication(scanBasePackages = "com.zhihao.miao")
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
Cat cat = context.getBean(Cat.class);
System.out.println(cat);
}
}
啟動并打?。?/p>

當然使用@SpringBootApplication(scanBasePackageClasses = MyConfig.class),指定scanBasePackageClasses參數(shù)的value值是你需要掃描的類也可以,結(jié)果一樣,不過如果多個配置類不在當前包及其子包下,則需要指定多個。
再看一個列子,
在上面的列子的相同包下(com.zhihao.miao.springboot)配置了People,并將其納入到spring容器中(@Component),我們知道@SpringBootApplication注解會掃描當前包及其子包,所以People類會納入到spring容器中去,我們需要將其排除在spring容器中,如何操作?
可以使用@SpringBootApplication的另外二個參數(shù)(exclude或excludeName)
package com.zhihao.miao.springboot;
import org.springframework.stereotype.Component;
@Component
public class People {
}
啟動類,
package com.zhihao.miao.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
People people = context.getBean(People.class);
System.out.println(people);
}
}
啟動并打印結(jié)果:

然后修改@SpringBootApplication配置,
package com.zhihao.miao.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication(exclude = People.class)
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =SpringApplication.run(Application.class,args);
People people = context.getBean(People.class);
System.out.println(people);
}
}
很明顯啟動報錯。使用@excludeName注解也可以。如下,
@SpringBootApplication(excludeName = {"com.zhihao.miao.springboot.People"})
參考文檔:
Springboot1.5.4官方文檔