开始使用spring boot
spring 项目需要根据 配置 来构建 ApplicationContext,并初始化项目中需要使用的组件,以及从什么地方去扫描组件。 所以 配置 对于spring项目来说有至关重要, 是spring的灵魂。
spring boot 提供了两种方式来定义配置:
- 在java代码中配置:
@Configuration
(推荐此种方式) - 基于XML文件配置: spring 一直以来的配置方式, 不做多于说明。 好也XML,坏也XML。
以下细说代码风格的配置
配置类 @Configuration
配置是spring的核心, 有@Configuration
注解的类, 会被spring认为是 spring 运行环境的 配置类, 至于配置类有多重要,看下面这段代码就知道了:
1 | public static void main(String[] args) { |
这是项目的运行入口, SpringApplication
运行参数,第一个参数 就是配置类。 可以说有配置类,才有SpringApplication
。它的作用就是告诉spring容器, 有哪些bean需要容器来管理。
1 | @Configuration |
例子中, Example
类作为配置类传给SpringApplication来启动spring 容器。 spring容器会执行Example
类在有@Bean
注解的方法,并把返回值作为一个组件管理起来。@Bean
注解没有设置 name
属性的话, 组件的名字默认就是方法名。 此例中,容器启动后会创建一个名为myRedis
的组件,需要使用myRedis
组件的地文, 用@AotoWired
或@Resource
注入就可以了。
导入其它配置类
对大型项目来说组件会非常多, 全都写在一个类里会很不雅。 这种问题用@Import
分分钟解决。 比如在上面的例子中,我们要加入数据库组件, 这时不想把所有组件都定义在一个类里, 那可以新建一个配置类,来创建数据组件:
1 | public class DbConfig { |
注意:DbConfig
类都不需要加@Configuration
注解。
然后在主配置类中,通过@Import
注解导入DbConfig
就可以了。
1 | @Configuration |
导入XML配置文件
配置类也可以用@ImportResource
注解导入xml配置文件,就不举例了。
自动配置
spring 自动配置功能会根据项目依赖的jar包,自动创建一些组件。 比如classpath里有HSQLDB
,而且我们又没有手动配置数据库链接组件的时候, spring就会自动配置一个嵌入式的db。 如果依赖了spring-boot-starter-web
,这个时候必须要启用自动配置,不然spring无法正常配置ServletWebServerApplicationContext
。
要启用自动配置, 只需要在任意一个有@Configuration
类上加@EnableAutoConfiguration
或@SpringBootApplication
就可以了。
替换自动配置
自动配置是非侵入式的, 当我们手动配置了某个bean的时候,对应的自动配置就不会生效。在启动项目时加--debug
命令行参数可以察看当前使用了哪些自动配置组件。
禁用特定的自动配置类
@SpringBootApplication
和 @EnableAutoConfiguration
都支持exclude
用户排除特定的自动配置类。
1 | import org.springframework.boot.autoconfigure.*; |
如查要排除的类 不在classpath中, 那可以作用excludeName
属性,属性值为要排除的类的全限定名。
还可以通过 设置spring.autoconfigure.exclude
属性来排除。
代码结构
spring对代码结构没有明确要求, 但是有一些最佳实践可以借鉴
不要使用默认包
默认包,就是没有包名。当 @ComponentScan
, @ConfigurationPropertiesScan
, @EntityScan
, @SpringBootApplication
注解使用在默认包的类上时, 会导致扫描所有依赖jar包里的所有类,这会导致扫描变慢, 而且可能会加载到一些并不想要的bean导致代码运行异常。
推荐严格遵循 java包命名规范 , 即按域名反转的形式来命名包。
应用主类的位置
推荐把主类放在项目根包里,位于所有其它类的上层。@SpringBootApplication
注解通常加在主类上, 这样就隐含扫包的基础包是当前项目的根包。 比如项目的根包名是 com.xxx.ademon
, 那主要就直接丢在com.xxx.ademon
下, 那隐含的扫包就是com.xxx.ademon
。
如果不想用@SpringBootApplication
那用 @EnableAutoConfiguration
和 @ComponentScan
也可以
bean 和依赖注入
标准spring框架的技术依然可以用来定义bean和注入依赖。
如果代码结构是按前面推荐的一致,那 @ComponentScan
可以不需要任务参数,项目里所有组件( @Component
, @Service
, @Repository
, @Controller
等)都会自动注册为spring bean。
以下示例中一个@Service
通过构造函数注入一个RiskAssessor
bean:
1 | package com.example.service; |
如果只有一个构造函数, 还可以省略@Autowired
注解:
1 | @Service |
使用 @SpringBootApplication 注解
使用@SpringBootApplication
让你立马拥有自动配置、组件扫描、定义额外配置项 的超能力。它相当于同时拥有以下三个功能:
@EnableAutoConfiguration
: 启用spring 自动配置机制@ComponentScan
: 启用组件扫描@Configuration
: 允许注册额外的bean,导入其它配置类。
1 | package com.example.myapplication; |
运行应用
IDE里运行
跟普通java程序一样, 直接运行主类main方法。
作为jar包运行
和普通jar包运行一样:
1 | $ java -jar target/myapplication-0.0.1-SNAPSHOT.jar |
如果运行jar包的时候, 还想开启debug端口:
1 | $ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n -jar target/myapplication-0.0.1-SNAPSHOT.jar |
通过maven 插件运行
进入到项目根目录执行:
1 | $ mvn spring-boot:run |
通过gradle插件运行
进入到项目根目录执行:
1 | $ gradle bootRun |
热部署
//todo
Developer Tools
spring boot 提供一系列工具,来提升开始过程的体验。 引入spring-boot-devtools
模块就可以享受这些工具带来的快乐了。
maven:
1 | <dependencies> |
grandle:
1 | dependencies { |
当应用以fully packaged
方式运行的时候,Developer Tools会自动禁用。当应用通过java -jar
或以特殊的class loader
启动时, spring会认为是在生产环境, 就会禁用Developer Tools, 可以通过设置spring.devtools.restart.enabled
系统属性来控制些行为。
设置-Dspring.devtools.restart.enabled=true
,那么不管应用是以什么class loader来启动的, 都会强制启用 Developer Tools。注意:生产环境千万别把这个属性设为true, 因为会带来安全风险。
要禁用 Developer Tools, 只需要排除spring-boot-devtools依赖包, 或者设置-Dspring.devtools.restart.enabled=false
。
引用依赖的时候maven里optional
设置为true
, Grandle里标记为developmentOnly
。
property 默认值
spring 支持的有些包会使用 cache 来提升性能, cache 在生产环境很有用处, 但是在开发时容易适得其反,导致开发者不能及时看到修改的内容, 出于这个原因,spring-boot-devtools 默认会禁用 cache 选项。
Cache 选项通常通过application.properties
文件来配置,例如 Thymeleaf 提供了spring.thymeleaf.cache
属性,比起手动设置这些属性, spring-boot-devtools 会在开发时自动设置合理的值。
由于开始Spring mvc
和spring WebFlux
程序时,开发者希望看到更多关于web request
的信息,spring-boot-devtools 允计为web
日志组使用DEBUG
日志,它会展示请求、处理请求的handler、响应等信息。 如果你还希望日志打印所有关于web请求的信息(包括可能潜在的敏感信息)可以打开spring.mvc.log-request-details
or spring.codec.log-request-details
配置属性。
提示: 如果不想使用property 默认值
功能,可以在application.properties
把spring.devtools.add-properties
设置为false
。
提示: devtools 涉及的全部 properties 可以查看DevToolsPropertyDefaultsPostProcessor
类:
1 | properties.put("spring.thymeleaf.cache", "false"); |
自动重启
使用 spring-boot-devtools 的应用,当 classpath 下的文件有变动时,会自动重启。当然某些资源比如静态资源、视图模板的变更不会触发自动重启。
触发重启: 由于spring-boot-devtools 监视classpath,所以触发重启的唯一方式就是更新classpath 里的内容。更新classpaht内容的方式取决于使用的IDE。Eclipse里保存修改过的文件就是引起classpath更新从而触发重启; IntelliJ IDEA 里构建项目(Build +→+ Build Project)有同样的效果。
// todo
打生产环境包
生产环境推荐打包为“可执行jar包”,所有的内容都在jar包内,基于云的部署也很方便。
更多生产环境特性比如:健康、运行指标、JMX , 可以考虑添加 spring-boot-actuator
。更多内容参考*production-ready-features.html*