一、JavaConfig
我们通常使用 Spring 都会使用 XML 配置,随着功能以及业务逻辑的日益复杂,应用伴随着大量的 XML 配置文件以及复杂的 bean 依赖关系,使用起来很不方便。
在 Spring 3.0 开始,Spring 官方就已经开始推荐使用 Java 配置来代替传统的 XML 配置了,它允许开发者将 bean 的定义和 Spring 的配置编写到到 Java 类中,不过似乎在国内并未推广盛行。当 Spring Boot 来临,人们才慢慢认识到 Java 配置的优雅,但是,也仍然允许使用经典的 XML 方式来定义 bean 和 配置 Spring。其有以下优势:
-
面向对象的配置。由于配置被定义为 JavaConfig 中的类,因此用户可以充分使用 Java 中的面向对象功能。一个配置类可以继承另一个,重写它的 @Bean 方法等。
-
减少或者消除 XML 配置。提供了一种纯 Java 的方式来配置与 XML 配置概念相似的 Spring 容器。
-
类型安全和重构友好。提供了一种类型安全的方法了来配置 Spring 容器,由于 Java 5 对泛型的支持,现在可以按类型而不是名称检索 bean,不需要任何的强制转换或者基于字符串的查找。
进行下面学习先搭建一个基于 Maven 构建的项目 java-config-demo,添加如下依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
1、XML 方式配置 IoC
1.1、定义两个 Bean
public class SomeBean {
private OtherBean otherBean;
public void setOtherBean(OtherBean otherBean) {
this.otherBean = otherBean;
}
public SomeBean() {
System.out.println("SomeBean 被创建");
}
public void init() {
System.out.println("SomeBean 被初始化");
}
public void destroy() {
System.out.println("SomeBean 被销毁");
}
// 省略 toString 方法
}
public class OtherBean {
public OtherBean() {
System.out.println("OtherBean 被创建");
}
}
1.2、编写配置
在 XML 配置文件中去配置这些 Bean 交给 Spring 管理。
<!-- applicationContext.xml -->
<bean id="someBean" class="cn.bean.SomeBean"/>
1.3、启动 Spring
启动 Spring 读取该 XML 文件创建容器对象,从容器中获取 SomeBean 对象。
public class IoCTest {
@Test
public void testXmlConfig() {
ApplicationContext ctx = new ClassPathXmlApplicationContexnt("classpath:applicationContext.xml");
SomeBean someBean = ctx.getBean(SomeBean.class);
System.out.println(someBean);
}
}
2、JavaConfig 方式配置 IoC
JavaConfig 方式中使用注解彻底的替代 XML 文件,那么到底要怎么告诉 Spring 容器,bean 没有定义在 XML 文件中,而是定义在一个 Java 配置类中。
-
@Configuration
:在类上贴该注解表示该类是 Spring 的配置类,具有 applicationContext.xml 文件的作用。 -
@Bean
:在 Spring 的配置类的方法上贴该注解后,该方法返回的对象会交给 Spring 容器管理,替代 applicationContext.xml 中的 bean 标签。 -
@ComponentScan
:在 Spring 配置类上贴该注解表示开启组件扫描器,默认扫描当前配置类所在的包,也可以自己指定,替代 XML 配置中的<context:component-scan />
标签。 -
AnnotationConfigApplicationContext
:该类是 ApplicationContext 接口的实现类,该对象是基于 JavaConfig 的方式来运作的 Spring 容器。
2.1、定义一个配置类
替代之前的 XML 文件,类中定义方法,返回 bean 对象交给 Spring 管理。
/**
* @Configuration
* 贴有该注解的类表示 Spring 的配置类
* 用于替代传统的 applicationContext.xml
*/
@Configuration
public class JavaConfig {
/**
* @Bean
* 该注解贴在配置类的方法上,该方法会被 Spring 容器自动调用
* 并且返回的对象交给 Spring 管理
* 相当于 <bean id="someBean" class="cn.bean.SomeBean"/>
*/
@Bean
public SomeBean someBean() {
return new SomeBean();
}
}
2.2、启动 Spring
加载配置类,启动 AnnotationConfigApplicationContext 容器对象,测试效果。
public class IoCTest {
@Test
public void testJavaConfig() {
// 加载配置类,创建 Spring 容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
// 从容器中取出 SomeBean 对象
SomeBean someBean = ctx.getBean(SomeBean.class);
System.out.println(someBean);
}
}
2.3、@Bean 注解中的属性
在 XML 配置 bean 的方式中,我们可以在 bean 标签中的 id,name,init-method,destroy-method,scope 等属性来完成对应的配置,在使用 JavaConfig 方式中我们也一样能通过相应的配置来完成同样的效果,这些效果大多封装到 @Bean 注解的属性中。@Bean 注解中的属性有以下:
-
name:对应 bean 标签中的 name 属性,用于给 bean 取别名;
-
initMethod:对应 bean 标签中的 init-method 属性,配置 bean 的初始化方法;
-
destroyMethod:对应 bean 标签中的 destroy-method 属性,配置 bean 的销毁方法。
注意:在配置类的方式中有许多的默认规定,比如:
-
bean 的 id 就是当前方法名;
-
配置多例则是在方法上添加
@Scope("prototype")
注解来实现,一般不用配,默认单例即可。
3、XML 方式配置 DI
<bean id="someBean" class="cn.bean.someBean">
<property name="otherBean" ref="otherBean"/>
</bean>
<bean id="otherBean" class="cn.bean.OtherBean"/>
4、JavaConfig 方式配置 DI
在配置类方式中我们有两种方式可以完成依赖注入,无论是哪种方式,前提都是要先把 bean 交给 Spring 管理,然后在把 bean 注入过去后再使用 setter 方法设置关系。通用步骤:先把两个 bean 交给 Spring 管理。
@Bean
public SomeBean someBean() {
SomeBean someBean = new SomeBean();
return someBean;
}
@Bean
public OtherBean otherBean() {
return new OtherBean();
}
4.1、通过方法形参注入
把需要注入的 bean 对象作为参数传入到另一个 bean 的方法声明中,形参名称最好跟 bean 的 id 一致。在容器里面有的 bean,都可以用这种方式注入。
// 在声明 SomeBean 的方法形参中直接注入 OtherBean 对象
@Bean
public SomeBean someBean(OtherBean otherBean) {
SomeBean someBean = new SomeBean();
someBean.setOtherBean(otherBean);
return someBean;
}
4.2、调用方法注入
// 调用上面已经声明的 otherBean 方法
@Bean
public SomeBean someBean() {
SomeBean someBean = new SomeBean();
someBean.setOtherBean(otherBean());
return someBean;
}
原理:Spring 容器在调用实例方法时,根据方法返回对象类型,判断容器中是否已经存在该类型的实例对象,如果不存在则执行实例方法,将返回对象实例交给容器管理,如果该实例已经存在了,直接从容器中拿已经存在实例对象方法,不执行实例方法。
5、使用 IoC DI 注解简化配置
以上案例中,在配置类内部去定义方法返回 bean 对象交给 Spring 管理的方式存在一个问题,就是如果需要创建的 bean 很多的话,那么就需要定义很多的方法,会导致配置类比较累赘,使用起来不方便。以前可以通过注解简化 XML 配置,现在同样也可以通过注解简化 JavaConfig,这里需要使用到 @ComponentScan 注解,等价于之前 XML 配置的 <context:component-scan base-package="贴了 IoC DI 注解的类所在的包"/>
。
@ToString
@Component
public class SomeBean {
private OtherBean otherBean;
@AutoWired
public void setOtherBean(OtherBean otherBean) {
this.otherBean = otherBean;
}
public SomeBean() {
System.out.println("SomeBean 被创建");
}
public void init() {
System.out.println("SomeBean 被初始化");
}
public void destroy() {
System.out.println("SomeBean 被销毁");
}
}
@Component
public class OtherBean {
public OtherBean() {
System.out.println("OtherBean 被创建");
}
}
<!-- applicationContext.xml -->
<context:component-scan base-package="cn.bean"/>
@Configuration // 表示该类是 Spring 的配置类
@ComponentScan // 开启组件扫描器,默认扫描当前类所在的包,及其子包
public class JavaConfig { }
若需要扫描的包不是配置类所在的包时,我们可以通过注解中的 value 属性来修改扫描的包。
注意:组件扫描的方式只能扫描我们自己写的组件,若某个 bean 不是我们写的,则还是要通过在配置类中定义方法来处理,两者是可以同时存在的。
6、Spring Test 方式加载配置类
首先在 pom.xml 添加如下依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.8.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.3</version>
<scope>test</scope>
</dependency>
6.1、JUnit4 的方式
6.1.1、基于 XML
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:XML文件路径")
public class IoCTest {
@Autowired
private SomeBean someBean;
@Test
public void test() {
System.out.println(someBean);
}
}
6.1.2、基于配置类
@ContextConfiguration
注解不仅支持 XML 方式启动 Spring 测试,也支持配置类的方式,配置 classes 属性来指定哪些类是配置类即可。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={配置类1.class, 配置类2.class, ...})
public class IoCTest {
@Autowired
private SomeBean someBean;
@Test
public void test() {
System.out.println(someBean);
}
}
6.2、JUnit5 的方式
注意测试类和测试方法都不用 public 修饰,测试类只需要贴 @SpringJUnitConfig
指定加载的配置即可。
@SpringJUnitConfig(配置类.class)
class IoCTest {
@Autowired
private SomeBean someBean;
@Test
void test() {
System.out.println(someBean);
}
}
7、配置类的导入
在 Spring 项目中一般都会有多个 Spring 的配置文件,分别配置不同的组件,最后关联到主配置文件中,该功能也是同样可以在配置类的方式中使用的。
7.1、XML 方式
<!-- 例如 mvc.xml 中导入 applicationContext.xml -->
<import resource="classpath:applicationContext.xml"/>
7.2、配置类方式
需要使用 @Import
来完成,指定导入的配置类。
// 主配置类
@Configuration
@Import(OtherJavaConfig.class) // 在主配置类中关联次配置类
public class JavaConfig { ... }
// 次配置类
@Configuration
public class OtherJavaConfig { ... }
// 测试
@SpringJUnitConfig(classes = JavaConfig.class) // 加载主配置类
public class IoCTest { ... }
7.3、配置类导入 XML 配置
需要使用 @ImportResource
来完成,指定导入 XML 配置文件的路径。
// 主配置类
@Configuration
@ImportResource("classpath:XML文件路径") // 在主配置类中关联 XML 配置
public class JavaConfig { ... }
// 测试
@SpringJUnitConfig(classes = JavaConfig.class) // 加载主配置类
public class IoCTest { ... }
二、Spring Boot 介绍
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。
人们把 Spring Boot 称为搭建程序的脚手架
。其最主要作用就是帮我们快速的构建庞大的 Spring 项目,并且尽可能的减少一切 XML 配置,做到开箱即用,迅速上手,让我们关注与业务而非配置。
该框架非常火,目前新开项目几乎都是基于 Spring Boot 搭建,非常符合微服务架构要求,企业招聘大多都要求有 Spring Boot 开发经验,属于面试必问的点。
1、优点
-
创建独立运行的 Spring 应用程序;
-
可嵌入 Tomcat,无需部署 war 文件;
-
简化 Maven 配置;
-
自动配置 Spring;
-
提供生产就绪型功能,如:日志,健康检查和外部配置等;
-
不要求配置 XML;
-
非常容易和第三方框架集成起来。
2、缺点
-
版本更新较快,可能出现较大变化;
-
因为约定大于配置,所以经常会出现一些很难解决的问题。
三、Spring Boot 快速入门
1、使用 IDEA 创建 Spring Boot 工程
Spring Boot 建议使用官方提供的工具来快速构建项目。IDEA 自带该功能,但需要联网使用。
注意:官方提供的构建工具默认只能选择固定的版本,有些版本之间的差异非常大,所以如果需要选择某个版本可以自行在 pom.xml 文件中修改版本。
1.1、勾选依赖
1.2、编写 Controller 代码
@Controller
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello() {
return "Hello Spring Boot";
}
}
然后通过 main 方法启动程序,观察控制台输出内容,最后浏览器中输入 http://localhost:8080/hello 验证效果。
1.3、启动类和测试类
使用 IDEA 创建的项目会自动生成一个启动类,其实本质也是一个配置类,如下:
@SpringBootApplication
public class XxxApplication {
public static void main(String[] args) {
SpringApplication.run(XxxApplication.class, args);
}
}
使用 IDEA 创建的项目会自动生成一个测试类,测试类贴有 @SpringBootTest
注解,可以通过通过注解属性指定加载的配置类,若没有指定,默认加载的是贴 @SpringBootApplication
注解的配置类,如下:
@SpringBootTest
class XxxApplicationTest {
// ...
}
2、创建普通 Maven 工程
2.1、添加依赖
<!-- 打包方式 jar -->
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2.2、编写 Controller 代码
@Controller
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello() {
return "Hello Spring Boot";
}
}
2.3、编写启动程序
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
然后通过 main 方法启动程序,观察控制台输出内容,最后浏览器中输入 http://localhost:8080/hello 验证效果。
3、疑问
-
当前项目继承的 spring-boot-starter-parent 项目有什么用?
-
导入的依赖 spring-boot-starter-web 有什么用?
-
占用 8080 端口的 Tomcat9 服务器哪来的?
-
之前的 Web 应用打包是 war,为什么现在的打包方式是 jar?
-
@SpringBootApplication 注解有什么用?
-
main 方法中执行的代码 SpringApplication.run(..) 有什么用?
四、入门案例分析
1、spring-boot-starter-parent
Spring Boot 提供了一个名为 spring-boot-starter-parent 的工程,里面已经对各种常用依赖(并非全部)的版本进行了管理,我们的项目需要以这个项目为父工程,这样我们就不用操心依赖的版本问题了,需要什么依赖,直接引入坐标即可!
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
</parent>
继承是 Maven 中很强大的一种功能,继承可以使得子 pom 可以获得 parent 中的部分配置(groupId,version,dependencies,build,dependencyManagement 等),可以对子 pom 进行统一的配置和依赖管理。
-
parent 项目中的 dependencyManagement 里的声明的依赖,只具有声明的作用,并不实现引入,因此子项目需要显式的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且 version 和 scope 都读取自父 pom;另外若子项目中指定了版本号,那么会使用子项目中指定的 jar 版本。
-
parent 项目中的 dependencies 里声明的依赖会被所有的子项目继承。
2、Spring Boot Starter
Spring Boot 非常优秀的地方在于提供了非常多以 spring-boot-starter-* 开头的开箱即用的 starter 启动器(依赖包),使得我们在开发业务代码时能够非常方便的、不需要过多关注框架的配置,而只需要关注业务即可。
Spring Boot 在配置上相比 Spring 要简单许多,其核心在于 spring-boot-starter, 在使用 Spring Boot 来搭建一个项目时,只需要引入官方提供的 starter,就可以直接使用,免去了各种配置。
官方目前已提供的常见的 Starter 如下 :
spring-boot-starter:核心启动器,提供了自动配置,日志和 YAML 配置支持。
spring-boot-starter-aop:支持使用
Spring AOP
和AspectJ
进行切面编程。spring-boot-starter-freemarker:支持使用
FreeMarker
视图构建 Web 应用。spring-boot-starter-test:支持使用
JUnit
,测试Spring Boot
应用。spring-boot-starter-web:支持使用
Spring MVC
构建 Web 应用,包括RESTful
应用,使用Tomcat
作为默认的嵌入式容器。spring-boot-starter-actuator:支持使用 Spring Boot Actuator 提供生产级别的应用程序监控和管理功能。
spring-boot-starter-logging:提供了对日志的支持,默认使用 Logback。
有关 Spring Boot Starter 命名规范,所有官方发布的 Starter 都遵循以下命名模式:spring-boot-starter-*
,其中 *
指特定的应用程序代号或名称。任何第三方提供的 Starter 都不能以 spring-boot
作为前缀,应该将应用程序代号或名称作为前缀,譬如 mybatis-spring-boot-starter
。
3、Web 启动器
这是 SpringBoot 提供的 Web 启动器,是一个快速集成 Web 模块的工具包,包含 Spring MVC,Jackson 相关的依赖,以及嵌入了 Tomcat9 服务器,默认端口 8080。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
需要注意的是,我们并没有在这里指定版本信息。因为 Spring Boot 的父工程已经对版本进行了管理了。
这个时候,我们会发现项目中多出了大量的依赖:
这些都是 Spring Boot 根据 spring-boot-starter-web 这个依赖自动引入的,而且所有的版本都已经管理好,不会出现冲突。
4、打包独立运行
对于 Spring Boot 项目来说无论是普通应用还是 Web 应用,其打包方式都是 jar 即可,当然 Web 应用也能打 war 包,但是需要额外添加许多插件来运行,比较麻烦。
默认的 Maven 打包方式是不能正常的打包 Spring Boot 项目的,需要额外的引入打包插件,才能正常的对 Spring Boot 项目打包,以后只要拿到该 jar 包就能脱离 IDE 工具独立运行了。
<!-- pom.xml 中添加插件 -->
<build>
<plugins>
<!-- Spring Boot 打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
-
使用 maven 的 package 命令进行打包;
-
使用命令
java -jar xxx.jar
运行 jar 包(--server.port=80)。
五、Spring Boot 参数配置
1、参数来源
-
命令行启动项目时传入的参数,如:
java -jar xxx.jar --server.port=80
; -
application.properties 或者 application.yml 文件。
一般用的比较多的就是直接在 application.properties 或者 application.yml 配置,其次是命令行启动方式。
1.1、application.properties 语法
server.port=80
server.session-timeout=30
server.tomcat.uri-encoding=UTF-8
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/rbac
spring.datasource.username=root
spring.datasource.password=admin
1.2、application.yml 语法
server:
port: 80
session-timeout: 30
tomcat.uri-encoding: UTF-8
spring:
datasource:
url: jdbc:mysql://localhost:3306/crm
username: root
password: admin
driverClassName: com.mysql.jdbc.Driver
2、配置优先级
一个项目中可以有多个配置文件存放在不同目录中,此时他们会遵循固定的优先级来处理有冲突的属性配置,优先级由高到底,高优先级的配置会覆盖低优先级的配置。用 application.properties 文件举例子,下面文件优先级由高到低排序:
-
项目/config/application.properties
-
项目/application.properties
-
classpath:config/application.properties
-
classpath:application.properties
一般都在 classpath:application.properties 做配置,其他方式不使用。
3、参数属性绑定
通过配置参数,来自定义程序的运行。一般配置参数编写 application.properties 或者我们自定义的 properties 文件中。
3.1、参数配置在自定义的 properties
回顾之前使用 XML 配置时,想让 Spring 知道我们指定自定义的 properties 文件,就需要如下配置:
# db.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/rbac
jdbc.username=root
jdbc.password=admin
<context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"/>
而现在使用 JavaConfig 配置,就得使用 @PropertySource
+ @Value
两个注解配合完成。@PropertySource
的作用就等价于上面那段 XML 配置。
/**
* @PropertySource:把属性配置加载到 Spring 的环境对象中
* @Value:从 Spring 环境对象中根据 key 读取 value
*/
@Configuration
@PropertySource("classpath:db.properties")
public class JavaConfig {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public MyDataSource dataSource() {
MyDataSource dataSource = new MyDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
3.2、参数配置在 application.properties
准备好 application.properties 和一个类 MyDataSource,配置如下:
# application.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/crm
jdbc.username=root
jdbc.password=admin
public class MyDataSource {
private String driverClassName;
private String url;
private String username;
private String password;
// 省略 toString 方法
}
3.2.1、@Value 绑定单个属性
在自定义的类上绑定属性如下:
@Component
public class MyDataSource {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
// 省略 toString 方法
}
@Configuration
@ComponentScan("上面类所在的包路径")
public class JavaConfig { }
在配置类上绑定属性如下:
@Configuration
public class JavaConfig {
// @Value:从 Spring 环境对象中根据 key 读取 value
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public MyDataSource dataSource() {
MyDataSource dataSource = new MyDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
3.2.2、@ConfigurationProperties 绑定对象属性
若觉得上面的方式比较笨重,可以把前缀编写到 @ConfigurationProperties
属性上,并且设置类属性与需要绑定的参数名相同,可实现自动绑定,但是注意 ,若是使用测试类加载贴有 @Configuration
的配置类,则需要在配置类中添加 @EnableConfigurationProperties
注解;若是使用测试类加载贴有 @SpringBootApplication
的配置类,则不需要。
@Component
@ToString
@Setter
@ConfigurationProperties(prefix="jdbc")
public class MyDataSource {
private String driverClassName;
private String url;
private String username;
private String password;
}
或者像下面这样配置:
@Bean
@ConfigurationProperties("jdbc")
public MyDataSource dataSource() {
return new MyDataSource();
}
@EnableConfigurationProperties
文档中解释:当 @EnableConfigurationProperties
注解应用到你的 @Configuration
时,任何贴 @ConfigurationProperties
注解的 beans 将自动被 Environment 进行属性绑定。
3.3、使用 Spring 的 Environment 对象绑定属性
当要绑定的参数过多时,直接在配置类中注入 Spring 的 Environment 对象, 这样就不需要贴上在字段或者形参上太多的 @Value
注解,相对比较简洁。
从 Environment 对象中可以获取到 application.properties
里面的参数,也可以获取到 @PropertySource
中的参数(即对配置在什么文件中没有要求)。
@Configuration
@PropertySource("classpath:db.properties")
public class JavaConfig {
/**
* environment:表示 Spring 的环境对象,该对象包含了加载的属性数据
* 可以获取到 application.properties 里面的参数,也可以获取到 @PropertySource 中的参数
* 但 application.properties 的优先级比 @PropertySource 高
*/
@Autowired
private Environment environment;
@Bean
public MyDataSource dataSource() {
MyDataSource dataSource = new MyDataSource();
dataSource.setDriverClassName(environment.getProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getProperty("jdbc.url"));
dataSource.setUsername(environment.getProperty("jdbc.username"));
dataSource.setPassword(environment.getProperty("jdbc.password"));
return dataSource;
}
}