大数跨境
0
0

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

SpringBoot自动装配原理+手写一个starter组件 终码一生
2024-07-09
0

点击“终码一生”,关注,置顶公众号

每日技术干货,第一时间送达!


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.propertiesApplication启动类都是不需要的

2.定义一个简单的Boy类

/**
 * @author suncong
 */

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
 */

@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
 */

@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.打包

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

7.再新建一个springboot项目

定义启动类和配置类

/**
 * @author SunCong
 */

@RestController
@SpringBootApplication
public class Demo1Application {

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

    @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>

8.测试

我们也可以修改配置文件

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

server.port=8081

demo.boy.name="shuaige"

搞定!!!

两类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是第三方的,自动配置类在

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

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

来源:juejin.cn/post/7195890214211534903

END


【福利】2023 高薪课程,全面来袭(视频+笔记+源码)


PS:防止找不到本篇文章,可以收藏点赞,方便翻阅查找哦。



往期推荐



SpringBoot 参数校验,高级特性,非常实用!

字符串拼接还在用StringBuilder?快试试Java8中的StringJoiner吧,真香!

面试官问:Java 序列化和反序列化为什么要实现 Serializable 接口?

巧用 MyBatis Plus 实现数据权限控制...

用 IDEA 这个神器看源码,效率贼高!

一个强大的分布式锁框架——Lock4j


【声明】内容源于网络
0
0
终码一生
开发者聚集地。分享Java相关开发技术(JVM,多线程,高并发,性能调优等),开源项目,常见开发问题和前沿科技资讯!
内容 1876
粉丝 0
终码一生 开发者聚集地。分享Java相关开发技术(JVM,多线程,高并发,性能调优等),开源项目,常见开发问题和前沿科技资讯!
总阅读739
粉丝0
内容1.9k