一、简介

在上篇博客初识Spring Boot框架中我们初步见识了SpringBoot的方便之处,很多小伙伴可能也会好奇这个Spring Boot是怎么实现自动配置的,那么今天我就带小伙伴我们自己来实现一个简单的Spring Boot 自动配置的案例,看看这一切到底是怎么发生的。
假设我的需求是这样的:当我的项目中存在某个类的时候,系统自动为我配置该类的Bean,同时,我这个Bean的属性还可以在application.properties中进行配置,OK,就这样一个需求,我们来看看怎么实现。

 

 

二、实践
 

1.新建starter的Maven项目

springboot Controller 自动生成 springboot自定义自动配置_右键

 

 

springboot Controller 自动生成 springboot自定义自动配置_spring_02

 

springboot Controller 自动生成 springboot自定义自动配置_spring_03

 

springboot Controller 自动生成 springboot自定义自动配置_自动加载_04

 

 

2.添加依赖 

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
      <version>1.4.2.RELEASE</version>
    </dependency>

 

3.属性配置

@ConfigurationProperties(prefix="hello")
public class HelloServiceProperties {
    private static final String MSG = "world";
    private String msg = MSG;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

这里就是一个简单的类,和上篇博客中我们提到的 类型安全的属性获取是一致的,这里属性的值我们可以在application.properties中来直接设置,如果不设置的话默认为world。

 

4.判断依据类

public class HelloService {
    private String msg;

    public String sayHello(){
        return "hello"+msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

我们一会的例子就是根据这个类是否存在来创建这个类的Bean,当然这个类也可以是第三方类库。

 

5.自动配置类

@Configuration
@EnableConfigurationProperties(HelloServiceProperties.class)
@ConditionalOnClass(HelloService.class)
@ConditionalOnProperty(prefix = "hello",value = "enable",matchIfMissing = true)
public class HelloServiceAutoConfiguration {
    @Autowired
    private HelloServiceProperties helloServiceProperties;

    @Bean
    public HelloService helloService(){
        HelloService helloService = new HelloService();
        helloService.setMsg(helloServiceProperties.getMsg());
        return helloService;
    }
}

这里@ConditionalOnClass注解主要是用来判断HelloService这个类在路径中是否存在,在存在且容器中没有该类的Bean的情况下系统会自动配置需要的Bean,@ConditionalOnProperty注解则表示指定的属性要满足的条件,在helloService方法中我们则使用了HelloServiceProperties提供的参数。
 

 

6.注册配置

在resources目录下新建META-INF目录,然后在META-INF目录下创建spring.factories文件,文件内容如下,表示设置自动配置类的位置,若有多个配置类用","隔开即可。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.HelloServiceAutoConfiguration

正常情况下我们按步骤一创建出来的Project是没有resources这个文件夹的,在IntelliJ IDEA这个工具中,我们需要先创建一个directory,然后将之设置为resources root即可,设置方式如下:选中resources目录右键单击–》Mark Directory as–》Resource Root。
 

 

7.在项目中使用

OK,经过上面几个步骤我们的自动配置功能就算死写好了,接下来我们要在自己的项目中来使用它了,正常情况下做好自动配置类之后我们需要将之上传到
maven 私服上然后直接在项目中引用,也可以将之安装到本地库,这里我选择后者的一个简化方式,直接创建Module来引用这个自动配置Module(如果小伙伴是用STS或者MyEclipse之类的开发工具直接创建新工程然后添加引用类库即可)。
创建Module方式很简单,选中刚才的Project右键单击,New一个Module,这个Module是一个SpringBoot项目(不清楚怎么创建SpringBoot项目可以查看这篇文章初识Spring Boot框架)

springboot Controller 自动生成 springboot自定义自动配置_右键_05

 

然后在新建Module的pom.xml文件中添加如下依赖:

<dependency>
            <groupId>com.example</groupId>
            <artifactId>springboot-test02</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

实际上就是我们刚刚创建的自动配置文件的坐标。然后修改新Module的入口类:

@RestController
@SpringBootApplication
public class UsemystarterApplication {

    @Autowired
    private HelloService helloService;

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

    @RequestMapping("/")
    public String index(){
        return helloService.sayHello();
    }
}

使用刚刚创建的HelloService,如果需要我们可以在application.properties中添加如下配置:

hello.msg = this is a autoconfig test!

运行Module,然后在浏览器中访问,结果如下:

springboot Controller 自动生成 springboot自定义自动配置_自动加载_06

 

如此说明自动配置成功!

为什么module项目可以直接注入使用HelloService? 它是怎么被创建的?

在启动类中有@SpringBootApplication注解,点开源码,它包含@EnableAutoConfiguration注解。@EnableAutoConfiguration的作用就是会自动加载jar包中spring.factories文件。spring.factories文件中org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxxxxxxx。等号后面是你定义的配置类。SpringBoot-Test02项目中创建了一个自定义的配置类,然后让spring自动加载。最后能直接@Autowired注入使用。