分析

Spring3.0 之前要使用 Spring 必须要有一个 xml 配置文件,而 Spring3.0 之后 注解 慢慢登上舞台,通过注解 @Configuration@Bean 可以代替 xml 配置文件

  • @Configuration 标注在类上,相当于把该类作为 spring 的 xml 配置文件中的 <beans> ,作用为配置 spring 容器(应用上下文)
  • @Bean 标注在方法上(返回某个实例的方法),等价于 spring 的 xml 配置文件中的 <bean> ,作用为注册 bean 对象

如果 spring 扫描到一个类加了 @Configuration 注解,那么这个类下面的 @bean 注解的返回对象就会注册到 spring 的容器里面,然后就能通过@Autowired 注解获取 bean

例子

配置类

找个实际的例子,比如说著名的分页插件:PageHelper,包下面有两个类,

第一个 PageHelperAutoConfiguration

只要 spring 容器扫描到这个类,就能把类下面的 bean 对象注册到 IOC 容器中

Properties 类

第二个类PageHelperProperties

该类上有一个 @ConfigurationProperties注解,通过与其他注解配合使用,能够实现 Bean 的按需配置。

在注解上配置有一个 prefix 属性,通过指定的前缀,绑定配置文件中的配置,该注解可以放在类上,也可以放在方法上

META-INF

SpringBoot 在启动的时候会扫描所有依赖的 jar 包下面的 META-INF 文件夹下面的 spring.factories 文件。
然后找这个文件的关键字org.springframework.boot.autoconfigure.EnableAutoConfiguration=\,这个关键字后面的全限定类名就是告诉 spring 要加载哪些@Configuration的类

所以要写一个自定义的自动装配组件大致需要如下工作

  • 新建一个 Maven 工程,写一个自己的 Properties类和@Configuration
  • META-INF文件夹下面创建 spring.factories 文件,配置自己刚刚的 Configuration类路径
  • 打包到 Maven 仓库
  • 新建 springboot 工程引用刚刚的包依赖进行测试

开始

创建 Maven 工程,导入依赖

1
2
3
4
5
6
7
8
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.0.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>

创建一个 Properties 类

用于接收配置文件配置的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.shiguang.autoconfigure;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
* @author shiguang
*/
@ConfigurationProperties(prefix = UserProperties.USER_PREFIX)
public class UserProperties {

public static final String USER_PREFIX = "user";

private String username;
private String password;
private String age;

public UserProperties() {
}

public UserProperties(String username, String password, String age) {
this.username = username;
this.password = password;
this.age = age;
}

public static String getUserPrefix() {
return USER_PREFIX;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}
}

自动配置类

作用是读取用户自定义配置数据并转换成一个 User 对象

User 类

1
2
3
4
5
6
7
public class User {
private String username;
private String password;
private String age;

//构造方法、get、set方法
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@EnableConfigurationProperties(UserProperties.class)
@Configuration
public class UserAutoConfiguration {

@Autowired
private UserProperties userProperties;

@Bean
public User user() {
User user = new User();
user.setUsername(userProperties.getUsername());
user.setPassword(userProperties.getPassword());
user.setAge(userProperties.getAge());
return user;
}
}

配置文件

resources 文件夹下创建 META-INFspring.factories

1
2
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.shiguang.autoconfigure.UserAutoConfiguration

整体

Maven 打包

mvn install 到本地仓库

测试

创建一个 SpringBoot 项目,导入本地仓库依赖

1
2
3
4
5
<dependency>
<groupId>org.example</groupId>
<artifactId>untitled</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

application.properties 文件中增加配置

1
2
3
user.username=shiguang
user.password=123456
user.age=18

创建一个 controller 用于测试

1
2
3
4
5
6
7
8
9
10
@RestController
public class UserController {
@Resource
private User user;

@GetMapping("/user")
public User getUser() {
return user;
}
}

启动 SpringBoot 的启动类,访问默认的 8080 端口

测试路径为:http://localhost:8080/user