likes
comments
collection
share

SpringBoot自动装配原理+手写一个starter组件

作者站长头像
站长
· 阅读数 16

springboot作为java开发者不得不提的一个框架,其中也是有许多配置可以减轻开发者的工作量。

简化了Bean对象注入到IoC容器中的流程(自动装配),配置文件的统一管理。

比如自动装配,引入一个starter就可以实现了,大大减少了代码量,使得coder专注于业务代码。

自动装配原理

首先你需要去熟悉SPI机制

具体的逻辑就不展示了,这里只展现关键代码。如果需要详细启动逻辑代码的同学评论走一波,需求多的话就更新。

springboot自动装配的流程

就是随着A项目的启动,会扫描到@SpringBootApplication注解

该注解里面存在一个@EnableAutoConfiguration注解

EnableAutoConfiguration注解里面又存在一个Import注解

执行selectImports方法,selectImports返回的是配置类的全路径名

配置类从何而来,是基于SPI机制,去classpath下的META-INF目录下找所有的spring.factories文件,然后将所有的spring.factories文件进行解析

自动将我所需要的Bean对象注入到IoC容器里面去,@Configuration@Bean,自动体现在我没有对任何类加前面的两个注解

手写一个starter

1.我们先新建一个springboot项目,这里的application.properties和Application启动类都是不需要的

SpringBoot自动装配原理+手写一个starter组件 2.定义一个简单的Boy类

/**
 * @author suncong
 * @Date 2023/2/3 17:24
 */
public class Boy{

    public static Boy create(String name){
        return new Boy(name);
    }

    private String name;

    public Boy(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String say(){
        return name+",Hello World!";
    }
}

3.定义自动配置类

/**
 * @author suncong
 * @Date 2023/2/3 17:26
 */
@ConditionalOnClass(Boy.class) // 加载到Boy这个类的话,就自动装配
@EnableConfigurationProperties(BoyProperties.class)
@Configuration
@Data
@ComponentScan
public class BoyAutoConfiguration {

    /**
     * 将对象交给IOC管理
     * @param boyProperties
     * @return
     */
   @Bean
    Boy boy(BoyProperties boyProperties){
       return new Boy(boyProperties.getName());
   }

}

4.定义ConfigurationProperties类,从配置文件(引用这个starter的项目的配置文件)中读取配置

/**
 * @author suncong
 * @Date 2023/2/3 17:28
 */
@ConfigurationProperties(prefix = "demo.boy")
public class BoyProperties {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

5.META-INF文件

注意这里的每个包名都要正确!!

比如META_INFspring,factories就是错的(别问我怎么知道的...)

additional-spring-configuration-metadata.json

这个文件可写可不写,主要是定义配置信息的内容(指定demo.boy.name必须是String类型)

{
  "properties": [
    {
      "name":  "demo.boy.name",
      "type":"java.lang.String",
      "description": "想跳舞的人",
      "defaultValue": "sc"
    }
  ]
}

spring.factories 这个文件必须写,配置自动装配的类的路径

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.sc.demo.BoyAutoConfiguration

6.打包

SpringBoot自动装配原理+手写一个starter组件

这样的话,本地的maven仓库就有了这个jar包(后续可以上传仓库或者直接发jar给别人用)

7.再新建一个springboot项目

定义启动类和配置类

/**
 * @author SunCong
 */
@RestController
@SpringBootApplication
public class Demo1Application {

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

    @Autowired
    private com.sc.demo.Boy boy;

    @GetMapping("/say")
    public String say(){

        return boy.say();
    }

}

application.properties:

# 应用名称
spring.application.name=demo1

server.port=8081

demo.boy.name="scscsc"

pom.xml:

    <dependency>
        <groupId>com.sc</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

SpringBoot自动装配原理+手写一个starter组件 8.测试

SpringBoot自动装配原理+手写一个starter组件

我们也可以修改配置文件

# 应用名称
spring.application.name=demo1

server.port=8081

demo.boy.name="shuaige"

SpringBoot自动装配原理+手写一个starter组件

搞定!!!

两类starter的区别

我们注意到有这么两个starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>

一个是xxx-starter, 一个是stater-xxx

区别: 1.starter命名规则不一样(如上) 2.xxx-starter是第三方的,自动配置类在

SpringBoot自动装配原理+手写一个starter组件

starter-xxx是官方的,自动配置类在

SpringBoot自动装配原理+手写一个starter组件

最后,感谢您的观看!欢迎点赞 关注,评论出本文的不足之处