Spring Boot初体验

来源:互联网 发布:网络销售渠道有哪2种 编辑:程序博客网 时间:2024/06/05 03:56

Spring Boot 入门例子和说明

  • 刚接触Spring Boot,记录一些简单入门的知识点;

Spring Boot能让我们以最简单的方式创建独立的、产品级别的基于Spring的应用。

本文大部分内容来自spring boot的官方文档,以及Youtube的入门讲解.

总的来说,你可以用很少的配置,并且以很简单优雅的方式启动你的Spring Boot应用。

  • Spring Boot设计者所想要解决的主要问题:

1、 为Spring应用的部署提供更为快捷的多途径的方式;

2、开箱即用,同样也可以快速修改默认设置;

3、为大项目提供一系列能共用的不需要编程支持的特性(例如嵌入式web容器、安全、度量、健康检查、外部配置);

4、不需要生成XML文件,也不需要配置XML文件

快速生成Demo项目

Spring提供在线生成项目的方式:start.spring.io

同样,访问在命令行访问该网站,可以获得命令行生成项目的方式;

curl http://start.spring.io

此处不以这种方式创建Demo项目。

手动创建Spring Boot项目

使用Maven来创建Spring Boot项目

  • 创建POM文件
<?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>myproject</artifactId>    <version>0.0.1-SNAPSHOT</version>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.7.RELEASE</version>    </parent>    <!-- Additional lines to be added here... --></project>

添加spring-boot-starter-parent的父引用,为了方便地添加依赖,Spring Boot 提供了很多 Starters。上面配置的starter-parent提供了很多Maven默认依赖,它还提供了dependencyManagement,这样,那些默认的依赖,可以不用version设置就继承过来了。

回顾一下以前的开发,如果需要开发Spring MVC 项目,需要引用很多的依赖,并且每个都需要自己引用(当然你也可以复制粘贴),有了Spring Boot的Starter之后,就能以简单的方式添加一个新的功能,比如Spring MVCJPAtest等等很多,Spring Boot提供了很多的Starter,具体可以访问:这里

Demo中将添加一个Spring MVC的服务,所以还需要在POM文件中添加web的支持,所以添加上如下的配置:

<dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency></dependencies>
  • 添加业务代码
@RestController@EnableAutoConfigurationpublic class Example {    @RequestMapping("/")    @ResponseBody    String home(){        return "Hello World\n";    }    public static void main(String[] args) {        SpringApplication.run(Example.class,args);    }}

熟悉Spring MVC的人应该很容易就辨别出,Example类是一个Controller,它提供了一个访问路径为/的服务,该服务返回一个字符串

Hello World。至于@EnableAutoConfiguration注解,该注解是告诉Spring Boot怎样去解析这个类,由于我们之前配置了spring-boot-starter-web,这个配置将引入Spring MVCTomcat,该注解将会假定我们需要创建一个Web项目。(好吧,它猜对了)

关于Starters和AutoConfiguration

AutoConfiguration和Starters结合起来能很好地发挥作用,但是这两者没有直接捆绑在一起,

Spring Boot允许开发者在Starter外部配置Jar依赖,这种情况下,它也能尽量满足配置需要。

此外还有一个main方法,这是SpringBoot项目和传统的Web项目不同的地方,SpringApplication.run方法创建了一个SpringApplication的代理,SpringApplication负责启动Spring Boot项目。同样,@EnableAutoConfiguration也会负责启动Spring环境和tomcat服务。

很好奇@EnableAutoConfiguration做了些什么事情,通过注释可以有一些发现:

它会尝试着去查找classpath下定义的Bean,这些Bean定义在spring.factories中

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\

org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\

org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\

org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\

org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\

org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\

org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\

org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\

org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\

org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\

org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\

org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\

org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\

org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\

org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\

org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\

org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\

org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\

org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\

org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\

很多,也就是说,在启动过程中,会去过一遍这些Configuration,看看是否符合被加载的条件,如果符合,就加载对应的上下文环境。

当然,这里只是做了简单的描述。

启动SpringBoot项目也只需要运行这个main方法即可。

同样也可以在项目目录下运行:mvn spring-boot:run

启动完成之后,访问本地8080端口,将返回如下的结果:

Hello World

停止服务,只需要按下Ctrl—C

  • 生成Jar包(不是war包)

很明显,如果要生成可以单独运行的jar包,jar包中就需要包含运行项目所有的依赖包。

一般情况下,按照依赖生成出来的jar包都会比较大,这样带来的好处是很简洁,不需要依赖其他的jar包就能执行。

但是这样也会带来jar包重名冲突,也不能很清晰地看到到底哪些jar包是被真正使用到的。

Spring Boot提供了一种新的方式来兼容这两方面的问题,它提供了spring-boot-maven-plugin插件,在build阶段,它会添加依赖的jar包。

<build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build>

如果需要去除添加的jar依赖,运行jar vtf xxxx.jar就会得到最原始的没有依赖的jar包。

  • 运行jar

java jar xxx.jar

同样也可以启动Spring Boot项目。

如果需要更换tomcat端口,需要在项目的application.properties中添加配置

server.port=8000

  • 监控

之前提到,Spring Boot提供了一套监控机制,可以在服务运行期间,完整监控服务的运行状态以及宿主机的情况;

添加上监控的依赖:

        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-actuator</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-remote-shell</artifactId>        </dependency>

重新运行服务,可以在Console中发现如下日志:

2017-10-05 23:33:50.823  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /metrics/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)2017-10-05 23:33:50.823  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /metrics ||  /metrics.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()2017-10-05 23:33:50.824  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /trace ||  /trace.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()2017-10-05 23:33:50.825  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /mappings ||  /mappings.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()2017-10-05 23:33:50.827  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /beans ||  /beans.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()2017-10-05 23:33:50.828  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /configprops ||  /configprops.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()2017-10-05 23:33:50.832  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /env/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)2017-10-05 23:33:50.835  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /env ||  /env.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()2017-10-05 23:33:50.838  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /loggers/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.LoggersMvcEndpoint.get(java.lang.String)2017-10-05 23:33:50.838  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /loggers/{name:.*}],methods=[POST],consumes=[application/vnd.spring-boot.actuator.v1+json || application/json],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.LoggersMvcEndpoint.set(java.lang.String,java.util.Map<java.lang.String, java.lang.String>)2017-10-05 23:33:50.839  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /loggers ||  /loggers.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()2017-10-05 23:33:50.839  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /dump ||  /dump.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()2017-10-05 23:33:50.841  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /health ||  /health.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,java.security.Principal)2017-10-05 23:33:50.842  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /info ||  /info.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()2017-10-05 23:33:50.845  INFO 31462 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[ /heapdump ||  /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException

访问 /metrics,将得到类似的结果:

{  "mem": 337766,  "mem.free": 120221,  "processors": 4,  "instance.uptime": 436478,  "uptime": 495497,  "systemload.average": 2.94091796875,  "heap.committed": 282112,  "heap.init": 131072,  "heap.used": 161890,  "heap": 1864192,  "nonheap.committed": 57048,  "nonheap.init": 2496,  "nonheap.used": 55653,  "nonheap": 0,  "threads.peak": 44,  "threads.daemon": 36,  "threads.totalStarted": 56,  "threads": 41,  "classes": 7135,  "classes.loaded": 7135,  "classes.unloaded": 0,  "gc.ps_scavenge.count": 9,  "gc.ps_scavenge.time": 164,  "gc.ps_marksweep.count": 2,  "gc.ps_marksweep.time": 177,  "httpsessions.max": -1,  "httpsessions.active": 0}

支持以JMX的形式查看和管理内部对象;

运行JConsole,连接我们运行的项目对应的Java进程;

除此之外,Spring Boot还支持以SSH的方式登录Manager后台:

在服务启动的时候,输出了类似这样的日志:

Using default password for shell access: e509d8bd-308b-447c-892d-90118ab11f28

利用这个口令,我们可以使用SSH命令,访问本地的manager命令行界面:

可以通过help查看支持的操作,例如:

> endpoint invoke healthEndpointendpoint invoke healthEndpoint{status=UP, diskSpace={status=UP, total=249821663232, free=189794660352, threshold=10485760}}

这些都是同样信息的不同展现形式。

  • 自定义监控

Spring Boot支持自定义的监控展示,例如,开发者可以加入自己定义的HealthIndicator;

    @Bean    HealthIndicator healthIndicator(){       return new HealthIndicator() {           @Override           public Health health() {               return Health.status("Hello, I am a health indicator.").build();           }       };    }

结果如下:

{  "status": "UP",  "healthIndicator": {    "status": "Hello, I am a health indicator."  },  "diskSpace": {    "status": "UP",    "total": 249821663232,    "free": 189796761600,    "threshold": 10485760  }}
  • 关于web容器

Spring Boot的目标是,Use it as a jar

-EOF-