01-Spring Boot项目初始化相关
项目结构
典型工程结构
com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
| +- CustomerController.java
|
root package
:com.example.myproject
,所有的类和其他package都在root package之下;- 应用主类:
Application.java
,该类直接位于root package
下。通常我们会在应用主类中做一些框架配置扫描等配置,我们放在root package下可以帮助程序减少手工配置来加载到我们希望被Spring加载的内容; com.example.myproject.domain
包:用于定义实体映射关系与数据访问相关的接口和实现com.example.myproject.service
包:用于编写业务逻辑相关的接口与实现;com.example.myproject.web
:用于编写Web层相关的实现,比如:Spring MVC的Controller等;
非典型工程结构
假设我们将com.example.myproject.web
包与上面所述的root package
:com.example.myproject
放在同一级,像下面这样:
com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
| +- CustomerController.java
|
这个时候,应用主类Application.java
在默认情况下就无法扫描到com.example.myproject.web
中的Controller定义,就无法初始化Controller中定义的接口。
那么如果,我们一定要加载非root package
下的内容怎么办呢?
方法一:使用@ComponentScan
注解指定具体的加载包,比如:
@SpringBootApplication
@ComponentScan(basePackages="com.example")
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
}
这种方法通过注解直接指定要扫描的包,比较直观。如果有这样的需求也是可以用的,但是原则上还是推荐以上面的典型结构来定义,这样也可以少写一些注解,代码更加简洁。
方法二:使用@Bean
注解来初始化,比如:
@SpringBootApplication
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
@Bean
public CustomerController customerController() {
return new CustomerController();
}
}
这种方法在业务开发的时候并不是特别推荐,更适合用于框架封装等场景
配置文件
自定义参数
我们除了可以在Spring Boot的配置文件中设置各个Starter模块中预定义的配置属性,也可以在配置文件中定义一些我们需要的自定义属性。比如在application.properties
中添加:
book.name=SpringCloudInAction
book.author=YYJ
然后,在应用中我们可以通过@Value
注解来加载这些自定义的参数,比如:
@Component
public class Book {
@Value("${book.name}")
private String name;
@Value("${book.author}")
private String author;
// 省略getter和setter
}
@Value
注解加载属性值的时候可以支持两种表达式来进行配置:
- 一种是我们上面介绍的PlaceHolder方式,格式为
${...}
,大括号内为PlaceHolder - 另外还可以使用SpEL表达式(Spring Expression Language), 格式为
#{...}
,大括号内为SpEL表达式
参数引用
在application.properties
中的各个参数之间,我们也可以直接通过使用PlaceHolder的方式来进行引用,就像下面的设置:
book.name=SpringCloud
book.author=YYJ
book.desc=${book.author} is writing《${book.name}》
book.desc`参数引用了上文中定义的`book.name`和`book.author`属性,最后该属性的值就是`YYJ is writing《SpringCloud》
使用随机数
在一些特殊情况下,有些参数我们希望它每次加载的时候不是一个固定的值,比如:密钥、服务端口等。在Spring Boot的属性配置文件中,我们可以通过使用${random}
配置来产生随机的int值、long值或者string字符串,这样我们就可以容易的通过配置来属性的随机生成,而不是在程序中通过编码来实现这些逻辑。
${random}
的配置方式主要有一下几种,读者可作为参考使用。
# 随机字符串
com.didispace.blog.value=${random.value}
# 随机int
com.didispace.blog.number=${random.int}
# 随机long
com.didispace.blog.bignumber=${random.long}
# 10以内的随机数
com.didispace.blog.test1=${random.int(10)}
# 10-20的随机数
com.didispace.blog.test2=${random.int[10,20]}
该配置方式可以用于设置应用端口等场景,避免在本地调试时出现端口冲突的麻烦
命令行参数
在启动Spring Boot应用时,可以使用java -jar
命令的方式。该命令除了启动应用之外,还可以在命令行中来指定应用的参数,比如:java -jar xxx.jar --server.port=8888
,直接以命令行的方式,来设置server.port属性,令启动应用的端口设为8888。
连续的两个减号--
就是对application.properties
中的属性值进行赋值的标识。
java -jar xxx.jar --server.port=8888
命令,等价于我们在application.properties
中添加属性server.port=8888
多环境配置
我们在开发任何应用的时候,通常同一套程序会被应用和安装到几个不同的环境,比如:开发、测试、生产等。其中每个环境的数据库地址、服务器端口等等配置都会不同,如果在为不同环境打包时都要频繁修改配置文件的话,那必将是个非常繁琐且容易发生错误的事。
对于多环境的配置,各种项目构建工具或是框架的基本思路是一致的,通过配置多份不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包,Spring Boot也不例外,或者说更加简单。
在Spring Boot中多环境配置文件名需要满足application-{profile}.properties
的格式,其中{profile}
对应你的环境标识,比如:
application-dev.properties
:开发环境application-test.properties
:测试环境application-prod.properties
:生产环境
至于哪个具体的配置文件会被加载,需要在application.properties
文件中通过spring.profiles.active
属性来设置,其值对应配置文件中的{profile}
值。如:spring.profiles.active=test
就会加载application-test.properties
配置文件内容。
加载顺序
- 命令行中传入的参数。
SPRING_APPLICATION_JSON
中的属性。SPRING_APPLICATION_JSON
是以JSON格式配置在系统环境变量中的内容。java:comp/env
中的JNDI
属性。- Java的系统属性,可以通过
System.getProperties()
获得的内容。 - 操作系统的环境变量
- 通过
random.*
配置的随机属性 - 位于当前应用jar包之外,针对不同
{profile}
环境的配置文件内容,例如:application-{profile}.properties
或是YAML
定义的配置文件 - 位于当前应用jar包之内,针对不同
{profile}
环境的配置文件内容,例如:application-{profile}.properties
或是YAML
定义的配置文件 - 位于当前应用jar包之外的
application.properties
和YAML
配置内容 - 位于当前应用jar包之内的
application.properties
和YAML
配置内容 - 在
@Configuration
注解修改的类中,通过@PropertySource
注解定义的属性 - 应用默认属性,使用
SpringApplication.setDefaultProperties
定义的内容
优先级按上面的顺序有高到低,数字越小优先级越高。
可以看到,其中第7项和第9项都是从应用jar包之外读取配置文件,所以,实现外部化配置的原理就是从此切入,为其指定外部配置文件的加载位置来取代jar包之内的配置内容。通过这样的实现,我们的工程在配置中就变的非常干净,我们只需要在本地放置开发需要的配置即可,而其他环境的配置就可以不用关心,由其对应环境的负责人去维护即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库