zoukankan      html  css  js  c++  java
  • Spring Boot应用开发起步

    Spring Boot应用的创建


    Spring Boot支持多种集成方式,如CLI,Maven,Gradle。这里以Mavan为例,一个典型的Maven Spring Boot应用需要满足Spring Boot的约定,比如最常用的从spring-boot-starter-web开始,那么项目的build脚本可以这样配置开始:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 
     3 <project xmlns="http://maven.apache.org/POM/4.0.0"
     4          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     5          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     6     <modelVersion>4.0.0</modelVersion>
     7 
     8     <groupId>com.example</groupId>
     9     <artifactId>cnblogs_example</artifactId>
    10     <version>1.0-SNAPSHOT</version>
    11 
    12     <parent>
    13         <groupId>org.springframework.boot</groupId>
    14         <artifactId>spring-boot-starter-parent</artifactId>
    15         <version>2.0.0.BUILD-SNAPSHOT</version>
    16     </parent>
    17 
    18 
    19     <dependencies>
    20         <dependency>
    21             <groupId>org.springframework.boot</groupId>
    22             <artifactId>spring-boot-starter-web</artifactId>
    23         </dependency>
    24     </dependencies>
    25 
    26     <!-- ignore others-->
    27 </project>

    一个基本的应用可以由Example.java的定义完成:

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @EnableAutoConfiguration
    public class Example {
    
        @RequestMapping("/")
        String home() {
            return "Hello World!";
        }
    
        public static void main(String[] args) throws Exception {
            SpringApplication.run(Example.class, args);
    
    }

    自此,一个完整,虽然简单的Spring Boot Web应用已经产生。当然,如果需要直接通过"mvn package"就可以生成一个all-in-one的可执行jar(Uber jar),我们还需要在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>cnblogs_example</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.0.BUILD-SNAPSHOT</version>
        </parent>
    
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <mainClass>Example</mainClass>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    </project>
    View Code

    这样就可以简单地通过“java -jar cnblogs_example-1.0-SNAPSHOT.jar”来运行这个web应用,并可以通过http://127.0.0.1:8080/来访问了,真的是很简单,而且可移植性强,一个jar文件在有Java运行时的地方都可以跑起来了。

     

    一些配置规范(COO)


    Application源 

    Application源指的是用SpringApplication搜索的Application的定义的集合。如示例中的 SpringApplication.run(Example.class, args); 用的就是“Class”类型的源,因为指定的是一个具体的Class。

    根据参考【2】,目前(v2.0)支持的sources类型有:

    • Class:能够被AnnotatedBeanDefinitionReader加载的Java类
    • Resource:能够被XmlBeanDefinitonReader加载的XML资源,或者能被GroovyBeanDefinitionReader加载的groovy script
    • Package:被ClassPathBeanDefinitionScanner扫描的Java包
    • CharSequence:依次尝试作为Java class,Resource, 和Java包加载。

     配置文件application.properties

    Spring Boot默认的配置文件甚至可以不存在,需要的话也很简单,只要在项目的“src/main/resources”目录下创建application.properties文件就可以了,很多配置就可以直接写在这里了,常用的配置有port,datasource等等。比如:

    server.port=9090
    
    spring.datasource.url = [url]
    spring.datasource.username = [username]
    spring.datasource.password = [password]
    spring.datasource.driverClassName = oracle.jdbc.OracleDriver
    spring.datasource.jmx-enabled=true

    #second db ... spring.secondDatasource.url = [url] spring.secondDatasource.username = [username] spring.secondDatasource.password = [password] spring.secondDatasource.driverClassName = oracle.jdbc.OracleDriver
    spring.secondDatasource.jmx-enabled=true

    顺便记录一下程序中datasource的引用方式:

    @Bean
    @Primary
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    这里虽然可以配置多个datasource,我们在项目中需要使用JMX查询bean,使用中发现,目前Spring Boot + Tomcat的使用中还只支持primary datasource的JMX暴露,而且名称固定为“dataSourceMBean”。

    应用是如何组织起来的?


    显然Spring Boot为我们隐藏了很多技术细节,包括启动过程,这里希望对其启动的原理做一点总结。

    简化的Maven父项目

    在上面示例项目中,继承了“spring-boot-starter-parent”项目,背后也为我们提供了很多便利性支持,比如自动具有了如下功能【1】

    • Java 1.6作为默认的编译级别
    • UTF-8编码
    • 依赖声明中可以省略<version>,默认从spring-boot-dependencies继承
    • 敏感信息过滤

    强大的包依赖和插件管理

    这本身是maven的特性,但Spring Boot通过提供maven的扩展插件为微服务的运行提供了很好的封装。比如,我们在项目中使用的几个插件:

    maven-dependency-plugin

    用于打包操作,把一些依赖的jar内容解压到项目源码列表中,以便通过一般jar的规范来引用。

    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
        <phase>prepare-package</phase>
        <goals>
            <goal>unpack-dependencies</goal>
        </goals>
        <configuration>
            <includeArtifactIds>foglight-agent</includeArtifactIds>
            <outputDirectory>${project.build.outputDirectory}</outputDirectory>
        </configuration>
        </execution>
    </executions>
    </plugin>
    maven-jar-plugin

    用于操作Uber-jar的manifest:

    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
        <manifestEntries>
            <Premain-Class>com.quest.pas.agent15.AgentPremain</Premain-Class>
            <Can-Redefine-Classes>true</Can-Redefine-Classes>
            <Can-Retransform-Classes>true</Can-Retransform-Classes>
        </manifestEntries>
        </archive>
    </configuration>
    </plugin>

    再比如,在加入“spring-boot-starter-web”依赖之后,Spring Boot就得到了如下的依赖,包含Tomcat和Spring Boot自身jar:

    D:WorkspaceMicroServicescnblogs_example>mvn dependency:tree
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] Building cnblogs_example 1.0-SNAPSHOT
    [INFO] ------------------------------------------------------------------------
    [INFO]
    [INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ cnblogs_example ---
    [INFO] com.example:cnblogs_example:jar:1.0-SNAPSHOT
    [INFO] - org.springframework.boot:spring-boot-starter-web:jar:2.0.0.BUILD-SNAPSHOT:compile
    [INFO]    +- org.springframework.boot:spring-boot-starter:jar:2.0.0.BUILD-SNAPSHOT:compile
    [INFO]    |  +- org.springframework.boot:spring-boot:jar:2.0.0.BUILD-SNAPSHOT:compile
    [INFO]    |  |  - io.projectreactor.addons:reactor-test:jar:3.0.5.RELEASE:compile
    [INFO]    |  |     - io.projectreactor:reactor-core:jar:3.0.5.RELEASE:compile
    [INFO]    |  |        - org.reactivestreams:reactive-streams:jar:1.0.0:compile
    [INFO]    |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.0.0.BUILD-SNAPSHOT:compile
    [INFO]    |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.0.0.BUILD-SNAPSHOT:compile
    [INFO]    |  |  +- ch.qos.logback:logback-classic:jar:1.2.2:compile
    [INFO]    |  |  |  +- ch.qos.logback:logback-core:jar:1.2.2:compile
    [INFO]    |  |  |  - org.slf4j:slf4j-api:jar:1.7.25:compile
    [INFO]    |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.25:compile
    [INFO]    |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
    [INFO]    |  |  - org.slf4j:log4j-over-slf4j:jar:1.7.25:compile
    [INFO]    |  +- org.springframework:spring-core:jar:5.0.0.BUILD-SNAPSHOT:compile
    [INFO]    |  - org.yaml:snakeyaml:jar:1.18:runtime
    [INFO]    +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.0.0.BUILD-SNAPSHOT:compile
    [INFO]    |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.12:compile
    [INFO]    |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.12:compile
    [INFO]    |  - org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.12:compile
    [INFO]    +- org.hibernate:hibernate-validator:jar:5.4.1.Final:compile
    [INFO]    |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
    [INFO]    |  +- org.jboss.logging:jboss-logging:jar:3.3.1.Final:compile
    [INFO]    |  - com.fasterxml:classmate:jar:1.3.3:compile
    [INFO]    +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.0.pr2:compile
    [INFO]    |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0.pr2:compile
    [INFO]    |  - com.fasterxml.jackson.core:jackson-core:jar:2.9.0.pr2:compile
    [INFO]    +- org.springframework:spring-web:jar:5.0.0.BUILD-SNAPSHOT:compile
    [INFO]    |  +- org.springframework:spring-aop:jar:5.0.0.BUILD-SNAPSHOT:compile
    [INFO]    |  +- org.springframework:spring-beans:jar:5.0.0.BUILD-SNAPSHOT:compile
    [INFO]    |  - org.springframework:spring-context:jar:5.0.0.BUILD-SNAPSHOT:compile
    [INFO]    - org.springframework:spring-webmvc:jar:5.0.0.BUILD-SNAPSHOT:compile
    [INFO]       - org.springframework:spring-expression:jar:5.0.0.BUILD-SNAPSHOT:compile
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------

    SpringApplication引导程序

     SpringApplication类为用户程序提供了引导程序的作用,启动方式为在用户的main方法中调用,SpringApplication的主要工作有,参考【2】

    • 根据classpath创建合适的ApplicationContxt实例
    • 为启动命令行参数注册CommandLinePropertySource,并作为Spring的属性对外暴露
    • 刷新ApplicationContext,加载所有的单例bean
    • 触发所有的CommandLineRunner beans。

    这里又会涉及大量的实现细节,也有很多文章做了详细的描述,可以通过搜索来加深理解。

    Spring Boot是什么? - Microservices话题


    要了解Spring Boot,还得了解一点它的自身身份定位,因为Spring Boot本身不是凭空而出的,它一定是为了解决某类问题而出现的,那么它要解决的问题就是Microservices的落地问题。这里主要是想梳理一下几个重要的概念,具体细节已经有很多文章参考了。

    Microservices

    Microservices,可以参考wikipedia的词条,注意这里带“s”结尾,它指的是微服务架构,或者更准确说是一种架构风格。如同其他架构风格一样,微服务也有它的历史源头和发展路径,到如今成为热门话题,也是因为它符合了历史潮流。从“认祖归宗”的角度来看,它还是属于“SOA”的一个实践方案。 背后的哲学思想是:“Do one thing and do it well”。也是现在的我自己正在并继续努力奉行的哲学。

    除了wikipedia之外,我看到这篇文章也对微服务架构做了很好的总结。

    Microservice chassis

    不确定这个词怎么翻译合适,先这么用着吧。为什么提到这个词,因为人们会吧Spring Boot定位为一种Microservice chassis,个人认为这是一种较为精确的分类,Pattern: Microservice chassis一文中也有详细的说明。从这个角度分类,这就好比Spring Boot诞生的背后的价值观,Spring Boot确切的说是用来解决我们实现Microservices过程中可能遇到的一些具体“麻烦”,是一种framework,方便开发者的工作。从前面的简单示例里面可以看到,真的使得开发变得很简单!

    Microservice chassis需要解决的实际问题包括:外部配置、日志、健康监控、运行状态和分布式的跟踪。

    Microservices框架

    我的理解,这是从另外一个角度来归类Spring Boot,这说明Spring Boot除了解决以上一些开发的具体“麻烦”琐事之外,还提供了更一般性的,可复用的软件开发和运行环境,包括支持指令、编译器、类库、工具集、API等来支持一个软件项目/系统的开发。

    对Spring Boot来说,它解决了基本的开发问题,通过依赖的方式提供了所有开发一个微服务系统的所需的所有功能,同时配合Spring Cloud就足够完备了。

    所以,chassis和框架很多时候是在一个系统都实现了,或者说一个完备的系统会同时满足chassis和框架的要求。

    References:


    【1】Spring Bootf官方文档:http://docs.spring.io/spring-boot/docs/current/reference/html/

    【2】: http://zhaox.github.io/java/2016/03/22/spring-boot-start-flow

    【3】:http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/SpringApplication.html

    【4】Spring Boot启动过程与回调接口汇总:https://segmentfault.com/a/1190000006918229

    【5】Microservices: https://en.wikipedia.org/wiki/Microservices

    【6】Microservice chassis: http://microservices.io/patterns/microservice-chassis.html

    版权申明: 欢迎分享,转载请注明出处http://www.cnblogs.com/1xin/p/6627054.html

  • 相关阅读:
    生成函数学习笔记
    CF1437F Emotional Fishermen
    BZOJ 1443 [JSOI2009]游戏Game
    BZOJ 1018 [SHOI2008]堵塞的交通traffic
    访问量破1000之记录
    BZOJ 1022 [SHOI2008]小约翰的游戏John
    BZOJ1457 棋盘游戏
    BZOJ1874: [BeiJing2009 WinterCamp]取石子游戏
    BZOJ 1188 [HNOI2007]分裂游戏
    Codeforces Round #345 (Div. 2)
  • 原文地址:https://www.cnblogs.com/1xin/p/6627054.html
Copyright © 2011-2022 走看看