SpringBoot官方文檔地址:
https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-documentation-about
Spring Boot簡(jiǎn)介
這里引用一下SpringBoot官網(wǎng)OverView頁(yè)面的介紹
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.
特點(diǎn)
- Create stand-alone Spring applications
創(chuàng)建獨(dú)立的Spring應(yīng)用程序 - Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
嵌入式Tomcat糟把,Jetty或Undertow(無(wú)需部署WAR文件) - Provide opinionated 'starter' dependencies to simplify your build configuration
提供自己的'starter'依賴來(lái)簡(jiǎn)化你的項(xiàng)目構(gòu)建配置 - Automatically configure Spring and 3rd party libraries whenever possible
盡可能自動(dòng)配置Spring以及第三方庫(kù) - Provide production-ready features such as metrics, health checks and externalized
configuration
提供生產(chǎn)就緒功能允蚣,如指標(biāo)蚤蔓,健康檢查和外部配置 - Absolutely no code generation and no requirement for XML configuration
絕對(duì)不會(huì)生成代碼,并且不需要XML配置
我的理解
以往的spring應(yīng)用往往需要大量的xml配置,為了改變這一現(xiàn)狀spring團(tuán)隊(duì)引入了java config(主要依賴@Configuration比庄、@Bean等注解)配置方案,但在整合第三方庫(kù)時(shí)依然需要配置很多固定的Bean,這和xml配置一樣仍然有些繁瑣沿盅,因此spring boot項(xiàng)目應(yīng)運(yùn)而生,采用自動(dòng)化配置方案簡(jiǎn)化spring應(yīng)用開(kāi)發(fā)的配置工作纫溃。
關(guān)于全java config的web項(xiàng)目可以參看我的github https://github.com/fulgens-cn/webapp
構(gòu)建項(xiàng)目
第一個(gè)SpringBoot項(xiàng)目以官網(wǎng)Guides頁(yè)面的Building a RESTful Web Service指導(dǎo)為例
構(gòu)建步驟
方法一:在 Spring Boot官方Initializer頁(yè)面 在線構(gòu)建工程再導(dǎo)入到Ide中
方法二:直接在Idea中Create New Project --> Spring Initializr --> 填寫(xiě)group腰涧、artifact -->鉤上web --> 點(diǎn)下一步就行了
工程目錄結(jié)構(gòu)
-src
-main
-java
-package
#主函數(shù),啟動(dòng)類紊浩,運(yùn)行它如果運(yùn)行了 Tomcat窖铡、Jetty、Undertow 等容器
-SpringbootApplication
-resouces
#存放靜態(tài)資源 js/css/images 等
- statics
#存放 html 模板文件
- templates
#主要的配置文件坊谁,SpringBoot啟動(dòng)時(shí)候會(huì)自動(dòng)加載application.yml/application.properties
- application.properties
#測(cè)試文件存放目錄
-test
# pom.xml 文件是Maven構(gòu)建的基礎(chǔ)费彼,里面包含了我們所依賴JAR和Plugin的信息
- pom.xml
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-boot-first-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-first-app</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
coding
創(chuàng)建實(shí)體類
com/example/springbootfirstapp/hello/Greeting.java
package com.example.springbootfirstapp.hello;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
創(chuàng)建controller
com/example/springbootfirstapp/hello/GreetingController.java
package com.example.springbootfirstapp.hello;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.atomic.AtomicLong;
@RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@RequestMapping("/greeting")
public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}
}
上面這個(gè)Controller非常簡(jiǎn)單,以下內(nèi)容是官網(wǎng)的解釋(值得注意的是解釋的最后兩段):
This controller is concise and simple, but there’s plenty going on under the hood. Let’s break it down step by step.
The @RequestMapping
annotation ensures that HTTP requests to /greeting
are mapped to the greeting()
method.
The above example does not specify
GET
vs.PUT
,POST
, and so forth, because@RequestMapping
maps all HTTP operations by default. Use@RequestMapping(method=GET)
to narrow this mapping.
@RequestParam
binds the value of the query string parameter name
into the name
parameter of the greeting()
method. If the name
parameter is absent in the request, the defaultValue
of "World" is used.
The implementation of the method body creates and returns a new Greeting
object with id
and content
attributes based on the next value from the counter
, and formats the given name
by using the greeting template
.
A key difference between a traditional MVC controller and the RESTful web service controller above is the way that the HTTP response body is created. Rather than relying on a view technology to perform server-side rendering of the greeting data to HTML, this RESTful web service controller simply populates and returns a Greeting
object. The object data will be written directly to the HTTP response as JSON.
This code uses Spring 4’s new @RestController
annotation, which marks the class as a controller where every method returns a domain object instead of a view. It’s shorthand for @Controller
and @ResponseBody
rolled together.
The Greeting
object must be converted to JSON. Thanks to Spring’s HTTP message converter support, you don’t need to do this conversion manually. Because Jackson 2 is on the classpath, Spring’s MappingJackson2HttpMessageConverter
is automatically chosen to convert the Greeting
instance to JSON.
啟動(dòng)第一個(gè)Spring Boot應(yīng)用
方法一:直接運(yùn)行SpringBootFirstAppApplication中的main方法
Although it is possible to package this service as a traditional WAR file for deployment to an external application server, the simpler approach demonstrated below creates a standalone application. You package everything in a single, executable JAR file, driven by a good old Java
main()
method. Along the way, you use Spring’s support for embedding the Tomcat servlet container as the HTTP runtime, instead of deploying to an external instance.
src/main/java/com/example/springbootfirstapp/SpringBootFirstAppApplication.java
package com.example.springbootfirstapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootFirstAppApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootFirstAppApplication.class, args);
}
}
@SpringBootApplication
注解加在SpringBoot應(yīng)用啟動(dòng)類上口芍,大致相當(dāng)于以下注解作用的集合:
@Configuration
標(biāo)注這個(gè)類為一個(gè)配置類@EnableAutoConfiguration
開(kāi)啟Spring Boot的自動(dòng)化配置功能- 通常你會(huì)為一個(gè)Spring MVC 應(yīng)用添加
@EnableWebMvc
注解, 但Spring Boot會(huì)當(dāng)類路徑下存在spring mvc時(shí)自動(dòng)添加箍铲。@ComponentScan
會(huì)使Spring掃描啟動(dòng)類所在包下的其他組件,如controller鬓椭。
啟動(dòng)類的mian()
方法中調(diào)用了Spring Boot的SpringApplication.run() 方法來(lái)啟動(dòng)一個(gè)應(yīng)用颠猴。不同于以往的web應(yīng)用关划,Spring Boot應(yīng)用沒(méi)有一行xml配置,也沒(méi)有web.xml文件翘瓮。100% pure Java and don’t have to deal with configuring any plumbing or infrastructure
方法二:maven命令啟動(dòng)
cd到項(xiàng)目主目錄后執(zhí)行(其中-Dtest.skip=true表示跳過(guò)單元測(cè)試)
mvn clean package
mvn spring-boot:run -Dtest.skip=true
當(dāng)然如果是Gradle構(gòu)建贮折,則可以執(zhí)行以下命令
gradle build
gradle bootRun
方法三:以java -jar的方式啟動(dòng)
maven打包完成后cd到target目錄下執(zhí)行以下命令,jar包名稱視自己情況而定
java -jar spring-boot-first-app-0.0.1-SNAPSHOT.jar
啟動(dòng)成功顯示大致如下:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.3.RELEASE)
2018-06-24 14:32:15.310 INFO 1959 --- [ main] c.e.s.SpringBootFirstAppApplication : Starting SpringBootFirstAppApplication on fulgensdeMacBook-Pro.local with PID 1959 (/Users/fulgens/IdeaProjects/SpringBootLearning/spring-boot-first-app/target/classes started by fulgens in /Users/fulgens/IdeaProjects/SpringBootLearning/spring-boot-first-app)
2018-06-24 14:32:15.314 INFO 1959 --- [ main] c.e.s.SpringBootFirstAppApplication : No active profile set, falling back to default profiles: default
2018-06-24 14:32:15.370 INFO 1959 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4eb92a67: startup date [Sun Jun 24 14:32:15 CST 2018]; root of context hierarchy
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/usr/local/dev/repository/org/springframework/spring-core/5.0.7.RELEASE/spring-core-5.0.7.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2018-06-24 14:32:16.378 INFO 1959 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2018-06-24 14:32:16.418 INFO 1959 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-06-24 14:32:16.418 INFO 1959 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.31
2018-06-24 14:32:16.435 INFO 1959 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/fulgens/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
2018-06-24 14:32:16.540 INFO 1959 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-06-24 14:32:16.540 INFO 1959 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1170 ms
2018-06-24 14:32:16.676 INFO 1959 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2018-06-24 14:32:16.679 INFO 1959 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-06-24 14:32:16.680 INFO 1959 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-06-24 14:32:16.680 INFO 1959 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-06-24 14:32:16.680 INFO 1959 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-06-24 14:32:16.811 INFO 1959 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-24 14:32:17.016 INFO 1959 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4eb92a67: startup date [Sun Jun 24 14:32:15 CST 2018]; root of context hierarchy
2018-06-24 14:32:17.122 INFO 1959 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/greeting]}" onto public com.example.springbootfirstapp.hello.Greeting com.example.springbootfirstapp.hello.GreetingController.greeting(java.lang.String)
2018-06-24 14:32:17.127 INFO 1959 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-06-24 14:32:17.129 INFO 1959 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-06-24 14:32:17.162 INFO 1959 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-24 14:32:17.163 INFO 1959 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-24 14:32:17.318 INFO 1959 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-06-24 14:32:17.365 INFO 1959 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2018-06-24 14:32:17.371 INFO 1959 --- [ main] c.e.s.SpringBootFirstAppApplication : Started SpringBootFirstAppApplication in 2.389 seconds (JVM running for 10.932)
瀏覽器輸入http://localhost:8080/greeting?name=SpringBoot返回如下內(nèi)容
單元測(cè)試
package com.example.springbootfirstapp.hello;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringRunner.class)
@SpringBootTest
public class GreetingControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext applicationContext;
@Before
public void init() {
// mockMvc = MockMvcBuilders.standaloneSetup(GreetingController.class).build();
mockMvc = MockMvcBuilders.webAppContextSetup(applicationContext).build();
}
@Test
public void greeting() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.GET, "/greeting?name=SpringBoot"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(MockMvcResultMatchers.jsonPath("$.id").isNumber())
.andExpect(MockMvcResultMatchers.jsonPath("$.content").isString())
.andExpect(MockMvcResultMatchers.content().json("{\"id\":1, \"content\":\"Hello, SpringBoot!\"}"));
}
}
spring boot 1.4.0 版本之前使用以下三個(gè)注解春畔,參考Spring Boot 系列(二)單元測(cè)試&網(wǎng)絡(luò)請(qǐng)求
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = DemoApplication.class) //在spring boot 1.4.0 版本之后取消了 //classes需要指定spring boot 的啟動(dòng)類如:DemoApplication.class 不然WebApplicationContext不被實(shí)例化
@WebAppConfiguration