最近项目用到了springboot,因好奇它怎么集成web容器(默认启动用的是tomcat)并启动的,所以看了看相关源码,这个系列就讲讲我自己看springboot相关源码的思路和心得吧。
为什么会有springboot这个东西呢,个人体会是这个框架大大简化了spring应用到初始搭建和开发过程,不再需要像原来spring项目那样有一大堆样板化的XML配置和复杂的依赖管理。简言之,springboot的设计理念是实现免XML的快速开发。所以对一般web开发中涉及的功能及其所需引入的框架和相关配置springboot都提供了默认的实现,如需修改这些默认实现,只需要在application.properties的配置文件中写个配置即可。
那么所谓的快速到底快到什么程度,先看下一个具体的例子。我用idea创建了一个maven工程,在pom文件中加入两个依赖,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>niwei.study.sample</groupId> <artifactId>spring-boot</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
可以看到,只引了spring-boot-starter-parent和spring-boot-starter-web两处依赖。接着新建一个Controller控制web请求:
package niwei.study.spring.boot.controller; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/springboot") public class HelloWorldController { @RequestMapping(value = "/{name}", method = RequestMethod.GET) @ResponseBody public String sayWorld(@PathVariable String name) { return "Hello " + name; } }
最后在controller类的父包下面建一个springboot应用的启动类:
package niwei.study.spring.boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication app = new SpringApplication(Application.class); app.run(args); } }
这样一个web应用就启动完了,可以看到控制台输出如下:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.3.2.RELEASE) 2016-03-13 22:55:40.877 INFO 557 --- [ main] niwei.study.spring.boot.Application : Starting Application on niwei-MBP.local with PID 557 (/Users/niwei/study/springboot-study/target/classes started by niwei in /Users/niwei/study/springboot-study) 2016-03-13 22:55:40.882 INFO 557 --- [ main] niwei.study.spring.boot.Application : No active profile set, falling back to default profiles: default 2016-03-13 22:55:40.961 INFO 557 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7ba18f1b: startup date [Sun Mar 13 22:55:40 CST 2016]; root of context hierarchy 2016-03-13 22:55:42.507 INFO 557 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'beanNameViewResolver' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]] 2016-03-13 22:55:43.404 INFO 557 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http) 2016-03-13 22:55:43.420 INFO 557 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat 2016-03-13 22:55:43.421 INFO 557 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.30 2016-03-13 22:55:43.539 INFO 557 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2016-03-13 22:55:43.539 INFO 557 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2585 ms 2016-03-13 22:55:43.905 INFO 557 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2016-03-13 22:55:43.910 INFO 557 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2016-03-13 22:55:43.910 INFO 557 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2016-03-13 22:55:43.910 INFO 557 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*] 2016-03-13 22:55:43.910 INFO 557 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 2016-03-13 22:55:44.230 INFO 557 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@7ba18f1b: startup date [Sun Mar 13 22:55:40 CST 2016]; root of context hierarchy 2016-03-13 22:55:44.312 INFO 557 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/springboot/{name}],methods=[GET]}" onto public java.lang.String niwei.study.spring.boot.controller.HelloWorldController.sayWorld(java.lang.String) 2016-03-13 22:55:44.314 INFO 557 --- [ 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.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2016-03-13 22:55:44.315 INFO 557 --- [ 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.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2016-03-13 22:55:44.346 INFO 557 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2016-03-13 22:55:44.346 INFO 557 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2016-03-13 22:55:44.388 INFO 557 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2016-03-13 22:55:44.521 INFO 557 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2016-03-13 22:55:44.620 INFO 557 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 2016-03-13 22:55:44.625 INFO 557 --- [ main] niwei.study.spring.boot.Application : Started Application in 4.675 seconds (JVM running for 5.478)
在浏览器输入相应地址:http://localhost:8080/springboot/world
以上就是用springboot搭建一个web应用示例的全部代码,一个依赖配置文件,一个控制器类,一个应用启动类,就OK了,就是这么快速!看起来就是这么简单,但看看maven里它引入的jar包:
还是不老少的,以前如果我们在项目里面自己引的话少不了一堆配置,而现在所有这些的默认配置都由springboot提供了。如果你想修改它提供的默认配置,比如例子中的端口号,也很简单,只需要在resource目录下建一个application.properties的文件,并配置如下:
server.port=${port:9999}
如此,访问web应用的端口号就由默认的8080改成了9999,以后所有修改springboot默认配置都是在这个文件中直接配。