使用SpringBoot(官方文档翻译)

本节展示了更多关于使用SpringBoot的细节。它包括了build系统、自动配置以及如何运行应用程序等。我们还介绍了一些使用Spring Boot的好习惯。尽管没有什么特别的,但有一些建议可以让您的开发过程变得更简单。

1.build系统

我们强烈建议你选择一个支持依赖管理的构建代码的系统工具。比如Maven或者Gradle。比可能也会选择别的,比如Ant,但是他们支持的不是很好。

1.1.依赖管理

每个springboot版本都会列出他所支持的依赖项的详细列表。实际上,您不需要在构建配置中为这些依赖项中的任何一个提供版本号,因为SpringBoot会为您管理这些依赖项。升级Spring Boot本身时,这些依赖项也会以一致的方式升级。

你任然可以提供一个版本号,就替取缔spring默认的版本,如果有必要的话。

Spring Boot的每个版本都与Spring框架的一个基本版本相关联。强烈建议您不要指定其版本。

1.2 maven

mave学习使用,请跳转到maven说明文档:

1.3 Starters启动器

starters是一堆你可以直接引用到你项目中的jar包依赖,你可以一站式的获得所有你所需要的spring和相关技术。而不需要去搜索样例代码,技术所需的依赖。比如:如果您想开始使用Spring和JPA进行数据库访问,在项目中直接添加spring-boot-starter-data-jpa依赖就行了。

springboot提供了以下启动器:(只列了几个)

名字描述


spring-boot-starter

核心启动器,包括自动话配置支持、日志 and YAML


spring-boot-starter-activemq

activemq启动器


spring-boot-starter-amqp

 Spring AMQP 和 Rabbit MQ启动器


spring-boot-starter-aop

面向切面的启动器(Spring AOP and AspectJ)

2.代码结构

springboot本身不要求代码结构。

2.1包命名

如果一个类开头没有包声明时,就是默认包下(src/mian/java路径下的类)。

这样可能会导致@ComponentScan、@ConfigurationPropertiesScan、@EntityScan或@SpringBootApplication注解出问题。

所以spring建议使用com.example.project这样的包命名方式。

2.2 定位主应用程序类

我们建议你将主应用程序类放在 root package 下,其他类的上层目录(如下面例子中的MyApplication.java类)。

com
 +- example
     +- myapplication
         +- MyApplication.java
         |
         +- customer
         |   +- Customer.java
         |   +- CustomerController.java
         |   +- CustomerService.java
         |   +- CustomerRepository.java
         |
         +- order
             +- Order.java
             +- OrderController.java
             +- OrderService.java
             +- OrderRepository.java

@SpringBootApplication注解放在主类上,他隐示的定义了基本的包扫描路径,他会扫描主类下层目录中的类(有兴趣可以试试放在自己定义的dao或者别的包下,看能不能扫描到同级包里的类)。

如果不想用@SpringBootApplication, 也可以用@ComponentScan和@EnableAutoConfiguration代替

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

 3.配置类(Configuration Classes)

springboot支持Java编码方式的配置。虽然使用XML也可以,但是我们建议你使用@Configuration。通常,主应用程序类可以作为一个主配置类。

3.1 引入额外的配置类

你不比将所有的配置都放在一个类里面。@Import注解可以用来引入额外的配置类(创建好bean对象)。或者,你可以使用@ComponentScan自动获取spring所有的component,包括带有@Configuration注解的类。

3.2 导入XML配置

如果你必须使用xml配置,我们任然建议你定义一个@Configuration注解的类,然后使用@ImportResource注解将xml配置引入。

4.自动配置

springboot自动配置,会根据你添加的jar包依赖,自动的配置你的应用程序。例如,如果你导入了HSQLDB包,但是没有手动配置任何数据库先关的连接对象,springboot也会自动配置一个内存数据库。

你需要通过添加@SpringBootApplication或者@EnableAutoConfiguration在你的其中一个配置类上来开启自动配置。

4.1 逐步取代自动配置

Springboot自动配置对代码没有入侵。任何时候,你都可以通过定义自己的配置来代替自动配置。比如,添加自己的DataSource bean,那么默认的配置就会被代替。

如果你需要查看项目中使用了哪些自动配置,以及为什么。可以通过添加--debug开关参数启动,这样就能记录相关日志到控制台。

idea中可以这样配置 

Positive matches:
-----------------

   AopAutoConfiguration matched:
      - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)

4.2 禁用特定的自动配置类

如果不想使用某些自动配置类,可以通过@SpringBootApplication的exclude属性去禁用。

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class MyApplication {

}

如果要禁用的类不再类路径下,也可以使用excludeName属性填写类名代替。如果你用的是@EnableAutoConfiguration开启的自动配置,这个注解也支持exclude和excludeName。最后,你还可以在配置文件中用spring.autoconfigure.exclude来定义要排除的自动配置类list

spring:
    autoconfigure:
        exclude: org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,org.springframework.boot.autoconfigure.aop.AopAutoConfiguration

注解方式可配置文件方式可以一起使用

虽然自动配置类是公用的,但只是指这些自动配置的类名可以被用来禁用自动配置。这些类的实际内容,比如嵌套的配置类,bean method仅供内部使用,我们不建议直接使用他们。

5.Spring Beans和依赖注入

你可以自由的使用标准的spring框架技术来定义bean以及为其注入依赖项,我们通常建议你使用构造函数的方式来注入bean,使用@ComponentScan去获取bean对象。

 如果你按我们建议的方式(之前讲的)安排代码结构,你可以直接使用@ComponentScan不需要任何参数,或者使用@SpringBootApplication(包含@ComponentScan),你所有的组件(@Component@Service@Repository@Controller等)都会被自动注册到spring bean对象中。

下面展示了一个service bean使用构造函数的方式来注入需要的RiskAssessor bean对象

@Service
public class MyAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    public MyAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }

    // ...

}

如果有多个构造函数,你需要通过@Autowired注解告诉spring使用哪个

@Service
public class MyAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    private final PrintStream out;

    @Autowired
    public MyAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
        this.out = System.out;
    }

    public MyAccountService(RiskAssessor riskAssessor, PrintStream out) {
        this.riskAssessor = riskAssessor;
        this.out = out;
    }

    // ...

}

 请注意如何使用构造函数将RiskAssessor申明为final,这表明,之后将不会被改变。

 6. 使用@SpringBootApplication注解

使用一个@SpringBootApplication可以支持一下三个功能:

  • @EnableAutoConfiguration 开启自动配置
  • @ComponentScan 开启组件扫描
  • @SpringBootConfiguration 在spring context中注册额外的bean,或者导入额外的配置类。是@Configuration的替代品,在集成测试中可以被自动发现。
@SpringBootApplication // 等同于 @SpringBootConfiguration @EnableAutoConfiguration
                        // @ComponentScan
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

@SpringBootApplication注解也支@EnableAutoConfiguration 和 @ComponentScan的定制化(禁用某些自动化配置、扫描路径配置)

介绍的这三个功能都不是必须的,你可以替代这些注解,比如,你不想使用组件扫描,下面的例子中,除了没有开启包扫描外,其他都一样。使用@Import明确的导入了用户自定义的配置类。

@SpringBootConfiguration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import({ SomeConfiguration.class, AnotherConfiguration.class })
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

 7. 运行你的项目

将你的程序打包成jar包,并使用了嵌入式的http服务器,这样做最大的好处是,你可以想运行别的程序一样运行你的项目程序,同样适用于debug。你不需要任何特殊的IDE插件或扩展。

7.1 使用IDE启动

你可以把springboot应用当做java程序在ide上启动。

如果你以外启动了2次,会有端口占用的报错(Port already in use),Spring Tools用户可以使用Relaunch按钮启动来确保关闭已有的实例。(得下载SpringTools, idea没有找到这个按钮,我一般是打开进程管理器,杀掉java进程)。

7.2 打包运行

如果你用Maven或者Gradle 将程序创建成了一个可执行jar包,就可以用java -jar来运行

$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar

也支持在运行的时候添加远程调试器:

$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
       -jar target/myapplication-0.0.1-SNAPSHOT.jar

7.3 使用maven

run快速变异和运行程序。

//启动
$ mvn spring-boot:run

//maven修改系统后环境变量
$ export MAVEN_OPTS=-Xmx1024m

7.4 使用Gradle

$ gradle bootRun
$ export JAVA_OPTS=-Xmx1024m

7.5 Hot Swapping (热启动)

springboot是普通的java程序,热启动应该是开箱即用的。JVM热启动受限与他可以替换的字节码,完整的解决方案,请看JRebel 

spring boot devtools模块还包括对快速应用程序重启的支持。有关详细信息,请看: Hot swapping “How-to”

8.Developer Tools(开发者工具)

SpringBoot有一些别的工具可以让开发者体验更好一些。spring-boot-devtools可以被任何项目引入,在开发的时候可以提供帮助。

maven方式:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

Gradle方式:

dependencies {
    developmentOnly("org.springframework.boot:spring-boot-devtools")
}

当运行一个完全打包的项目时,工具会自动禁止。如果你的项目是通过java -jar或者特殊的classloader启动,会被认为是生产环境项目。你也可以使用系统参数来控制,-Dspring.devtools.restart.enabled=true来启动,-Dspring.devtools.restart.enabled=false禁止。

在maven中把依赖标记为可选的(<optional>true</optional>),这Gradle中使用developmentOnly,防止devtools被传递到别的模块中。(如果其他项目依赖你的项目,<optional>true</optional>可以防止devtools被包含进去)

如果devtools的远程功能。maven需要这样设置。 

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

 8.1 属性默认值 

SpringBoot支持的一些库可以通过使用缓存来提高性能。比如模块引擎(例如:Thymeleaf)缓存可以避免重复的编译template文件。Spring MVC可以添加HTTP缓存头来应答静态资源的访问。

虽然缓存在生产环境有好处,但在开发过程中会适得其反,会导致你看不到刚刚做的修改。因此spring-boot-devtools默认禁止缓存功能。

缓存选项通常是在application.properties文件中设置。比如Thymeleaf通过spring.thymeleaf.cache属性设置

因为在开发SpringMVC和Spring WebFlux的时候需要详细的网络请求的信息,所以developer-tools建议你给web日志记录组开启debug日志记录。这样就会给你展示进入的请求、那个handler处理请求、返回的response信息等。如果你想记录所有的请求详情(包括敏感信息),你可以开启spring.mvc.log-request-details或者spring.codec.log-request-details配置属性。

如果你不香使用默认值,你可以在配置文件里面设置spring.devtools.add-properties=false

开发者工具完整的属性列表:DevToolsPropertyDefaultsPostProcessor.

8.2 自动重启

使用spring-boot-devtools后,当classpath下的文件被修改,项目就会自动重启。 在使用IDE开发的时候很有用,因为当代码被修改的时候反馈很快。请注意,某些静态资源、视图模板等不需要重启项目。

触发启动:

DevTools只监听classpath资源,唯一触发启动的方式就是更新classpath下的资源。更新classpath资源的方式取决于你使用的IDE:

  • Eclipse 需要手动保存才能触发。
  • IntelliJ IDEA :需要building project
  • maven: mvn compile

当与LiveReload一起使用时,自动重启效果会非常好,这个接下来会说。

DevTools依赖springboot的shutdown hook在重启的时候关闭。如果SpringApplication.setRegisterShutdownHook(false),会导致他出问题。

使用AspectJ时不支持自动重启。

Restart 和 Reload

重启技术使用2中类加载器。那些不会被修改的类(第三方jar包)被加载到基础的类加载器中。你正在开发的类被加载到重启类加载器中(restart classloader)。当项目重启的时候,会丢弃现有的重启类加载器,创建一个新的加载器。这意味着比完全启动更快。

8.2.1 记录变化

每次重启都会记录变化。可以通过设置去禁止。

spring.devtools.restart.log-condition-evaluation-delta=false

8.2.2 排除资源

某些资源被修改的时候没必要重启。比如Thymeleaf页面。默认情况下,/META-INF/maven/META-INF/resources/resources/static/public, or /templates这些目录下的资源不会触发重启,但会触发live reoad。你可以使用spring.devtools.restart.exclude定制化排除那些资源。比如只排除/static /public

spring.devtools.restart.exclude=static/**,public/**

如果你想保留默认的排除,添加额外的排除,可以使用spring.devtools.restart.additional-exclude

8.2.3 监听额外的路径

你可以使用spring.devtools.restart.additional-paths属性去配置监听额外的路径。你可以使用spring.devtools.restart.exclude你配置额外路径下的修改是触发重启还是live reload。

spring.devtools.restart.exclude的优先级高。两个同时设置相同目录,结果是被排除。

8.2.4 禁用Restart

如果你不想使用重启功能,你可以使用spring.devtools.restart.enabled属性来禁用。大多数情况下,我们使用的是配置文件的方式(这样任然会初始化restart classloader,但不会监听文件修改)。

如果想要完全禁止,你需要在调用SpringApplication.run(…​)方法前设置spring.devtools.restart.enabled的系统参数为false:

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(MyApplication.class, args);
    }

}

8.2.5 使用触发器文件

如果你使用IDE一直不间断的修改文件,你或许更希望只在特定时间restart。这种情况下,你可以使用触发器文件(trigger file),只有这个文件被修改才会触发重启检查。

使用这个功能,需要在以下目录添加文件:

src
+- main
   +- resources
      +- .reloadtrigger

然后添加配置:

spring.devtools.restart.trigger-file=.reloadtrigger

现在,只有.reloadtrigger文件被修改才会restart。

8.2.6 定制Restart Classloader

上面说的Restart和Reload,restart功能使用了2个类加载器。对于大多数项目,表现很好。但是有时候会造成类加载问题。

默认情况下,在你IDE上,任何项目都被restart类加载器加载, .jar文件都被base类加载器加载。如果是多模块项目,没有将所有模块都导入IDE,你需要定制话一些东西。如果是这样的话,你可以创建一个META-INF/spring-devtools.properties文件。

spring-devtools.properties文件可以包含restart.exclude和restart.include前缀的属性。include属性设置的是被restart类加载器加载的项,exclude属性设置的是被base类加载器加载的项。属性的值是正则匹配的:

restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\\.]+\\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\\.]+\\.jar

8.2.7 局限性

restart功能对于标准输入流反序列化出来的对象效果不是很好,如果你想反序列化数据,你或许需要使用spring的ConfigurableObjectInputStream和Thread.currentThread().getContextClassLoader()

不幸的是,一些第三方的lib没有考虑到这点,如果你遇到问题,你需要给作者提fix。

8.3 LiveReload

spring-boot-devtools模块包含一个LiveReload服务,当资源修改的时候,可以触发浏览器刷新。LiveReload浏览器插件Chrome是免费的,Firefox and Safari从 livereload.com下载。

如果想禁用这个服务:spring.devtools.livereload.enabled=false

同一时刻只能运行一个LiveReload服务,就算运行多个项目,只有第一个项目会有这个服务。

只有自动restart开启,才能触发LiveReload

8.4 全局设置

devtools全局设置通过在$HOME/.config/spring-boot目录下添加以下文件中的任何一个:

$HOME指的是当前用户目录。

  1. spring-boot-devtools.properties

  2. spring-boot-devtools.yaml

  3. spring-boot-devtools.yml

在这些文件中添加的配置会应用到你机器上所有使用了devtools的spring项目。比如之前说的触发器文件属性配置,就可以放到全局文件里。

spring.devtools.restart.trigger-file=.reloadtrigger

如果devtools配置文件在$HOME/.config/spring-boot目录下没有找到,就会在$HOME目录下搜索是否有.spring-boot-devtools.properties文件。这样可以让你给那些不支持$HOME/.config/spring-boot路径的项目分享全局配置文件。

8.4.1 配置FileSystemWatcher

FileSystemWatcher每隔一段时间就会检测一次class是否有修改,然后等待预设的静默期保证没有别的修改。由于springboot完全依赖IDE编译和拷贝文件到springboot可以访问的目录下,你可能会发现,当项目restart的时候,某些修改不会生效。这个时候你可以尝试增加spring.devtools.restart.poll-interval 和 spring.devtools.restart.quiet-period参数的值:

spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period=1s

现在每2秒检查一次classpath的修改,1秒静默期后确保咩有别的修改。 

8.5 远程项目

Spring Boot developer tools不止用于本地项目,远程项目也能使用他们的一些功能。远程支持是可选的,因为这样会带来一些安全风险。只应该在信任的网络上或者有ssl保护时使用,否则就不该使用。一定不要在生产环境使用DevTools的远程功能。

使用的时候,pom导入包之后,再添加以下配置:

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

然后设置spring.devtools.remote.secret属性,属性的值应该和其他重要的密码一样,不会被别人才出来。

Remote devtools支持的功能分为2个:接受连接的服务端端点、运行在IDE的客户端应用程序。

spring.devtools.remote.secret属性设置后,服务端组件自动开启。客户端组件需要手动启动。

8.5.1 运行远程客户端应用

远程客户端程序在IDE上,运行org.springframework.boot.devtools.RemoteSpringApplication。本地项目需要和远程项目有相同的目录结构。本地项目唯一的参数就是你需要连接的远程服务。

具体步骤,加入你的项目名为my-app:

  • 选择启动配置
  • 创建一个新的Java Application配置
  • 地址为my-app项目
  • 使用org.springframework.boot.devtools.RemoteSpringApplication作为main class
  • Program arguments添加远程url

运行信息:

  .   ____          _                                              __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _          ___               _      \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` |        | _ \___ _ __  ___| |_ ___ \ \ \ \
 \\/  ___)| |_)| | | | | || (_| []::::::[]   / -_) '  \/ _ \  _/ -_) ) ) ) )
  '  |____| .__|_| |_|_| |_\__, |        |_|_\___|_|_|_\___/\__\___|/ / / /
 =========|_|==============|___/===================================/_/_/_/
 :: Spring Boot Remote :: 2.5.6

2015-06-10 18:25:06.632  INFO 14938 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Starting RemoteSpringApplication on pwmbp with PID 14938 (/Users/pwebb/projects/spring-boot/code/spring-boot-project/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code)
2015-06-10 18:25:06.671  INFO 14938 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a17b7b6: startup date [Wed Jun 10 18:25:06 PDT 2015]; root of context hierarchy
2015-06-10 18:25:07.043  WARN 14938 --- [           main] o.s.b.d.r.c.RemoteClientConfiguration    : The connection to http://localhost:8080 is insecure. You should use a URL starting with 'https://'.
2015-06-10 18:25:07.074  INFO 14938 --- [           main] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2015-06-10 18:25:07.130  INFO 14938 --- [           main] o.s.b.devtools.RemoteSpringApplication   : Started RemoteSpringApplication in 0.74 seconds (JVM running for 1.105)

如果想要使用代理连接,使用spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port属性配置

8.5.2 远程更新 

任何本地的更新都会被推送到远程项目,触发远程项目的restart。如果你使用远程服务,这会很有帮助。通常,远程更新和重启比重新编译打包部署快的多。

当开发环境很慢的时候,静默期可能会不够,导致你的修改被分为很多批次。远程服务在第一批次的时候重启,其他批次不会被发送到远程服务,因为服务正在重启。

这种情况通常会有某些classes上传失败的告警以及重试的日志,也可能造成代码不一致或者在第一批次代码上传后导致无法启动。出现这些问题,可以尝试去增加spring.devtools.restart.poll-interval和spring.devtools.restart.quiet-period属性的值。

9.打包你的项目

可执行jar包可以用在生产环境。因为他们是自包含的(可独立运行),因此也非常适用于基于云的部署。

10.下一步

现在你应该知道了如何使用springboot,以及应该遵循的一些好的习惯。现在你可以继续深入了解springboot的特性,也可以跳过直接去了解生产环境搭建相关的内容。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七号公园的忧伤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值