首页 > 其他分享 >手写自定义springboot-starter,感受框架的魅力和原理

手写自定义springboot-starter,感受框架的魅力和原理

时间:2022-10-20 09:44:48浏览次数:75  
标签:springboot 自定义 spring 配置 boot autoconfigure org starter

一、前言

Springboot的自动配置原理,面试中经常问到,一直看也记不住,不如手写一个starter,加深一下记忆。
看了之后发现大部分的starter都是这个原理,实践才会记忆深刻。
核心思想:约定大于配置

二、初探starter启动原理

我们直接看看官网的starter是怎么设计的,仿照这写一个就行了!

我们Ctrl点击<artifactId>spring-boot-starter-web</artifactId>,进入内部pom,我们发现里面有个

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>2.5.3</version>
  <scope>compile</scope>
</dependency>

在此Ctrl点击<artifactId>spring-boot-starter</artifactId>进入starter内部pom:
我们发现之后干活的就是这个包依赖:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-autoconfigure</artifactId>
  <version>2.5.3</version>
  <scope>compile</scope>
</dependency>

在这里插入图片描述

我们现在创建两个项目即可:

  • spring-boot-starter(启动器)
  • spring-boot-starter-autoconfigure(自动配置包)

小编看到官方这么写的提醒,大家可以按照官网的进行起名称,不要学小编哈!!

您应该确保为您的启动器提供适当的命名空间。不要以 . 开头的模块名称spring-boot,即使您使用不同的 Maven groupId。我们将来可能会为您自动配置的内容提供官方支持。
根据经验,您应该在启动器之后命名组合模块。例如,假设您正在为“acme”创建一个启动器,并且您命名自动配置模块acme-spring-boot和启动器acme-spring-boot-starter。如果您只有一个模块将两者结合起来,请将其命名为acme-spring-boot-starter.

三、项目搭建

1. 新建空白项目

在这里插入图片描述
输入总的项目名称
在这里插入图片描述
在空白项目里新建两个,这里可以分开单独建立,这里小编跟着雷神一样了,就不单独建立项目了!!

在这里插入图片描述

2. 新建maven项目

在这里插入图片描述
包名和名称:

在这里插入图片描述

3. 新建springboot项目

在这里插入图片描述

4. 项目架构

这里把没有用的都删除了!!可以不删
在这里插入图片描述

四、配置

1. 在starter项目中引入自己的autoconfigure依赖

就是上面建立项目的设置的

<dependencies>
    <dependency>
        <groupId>com.wang</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

在这里插入图片描述

2. spring-boot-autoconfigure pom配置

<properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>${spring-boot.version}</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
    </dependency>
</dependencies>

还是把没用的东西删除了,剩余如下图:

在这里插入图片描述

五、编写autoconfigure项目

1. 配置一个bean

首先删除了自动启动类,咱们用不到,
spring-boot-autoconfigure项目中新建一个bean,此时不需要让这个bean在容器中,我们写一个自己配置,让他自动加入到容器中。
这就是自动配置的思想

/**
 * 这里不需要让在容器中,我们写一个自己配置,让他自动加入到容器中
 * @author wangzhenjun
 * @date 2022/10/14 16:26
 */
public class HelloService {

    @Autowired
    private MyProperties myProperties;

    public String HelloWord (String username){
        return myProperties.getPrefix() + username + myProperties.getSuffix();
    }
}

2. 编写一个配置文件

这里为了获取配置文件中的属性值,springboot自动配置源码里大部分都是,这样实现在一个配置文件中书写,其他的可以按照开头获取到属性和值!!


/**
 * @author wangzhenjun
 * @date 2022/10/14 16:28
 */
@Data
@ConfigurationProperties("wang.name")
public class MyProperties {

    private String prefix;
    private String suffix;
}

3. 编写自动配置

import com.wang.springbootautoconfigure.properties.MyProperties;
import com.wang.springbootautoconfigure.service.HelloService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author wangzhenjun
 * @date 2022/10/14 16:33
 */
@Configuration
//没有这个bean的时候才会生效
@ConditionalOnMissingBean(HelloService.class)
// 加载配置文件,让它成为容器中的bean
@EnableConfigurationProperties(MyProperties.class)
public class ServiceAutoConfiguration {
	
	
	/**
	 * 把刚刚写的服务,加入到容器中
	 */
    @Bean
    public HelloService helloService (){
    	
        return new HelloService();
    }
}

主要就是condition下的几个注解,来完成bean是否加入到容器中:
常用的:

  • @ConditionalOnClass
  • @ConditionalOnMissingClass
  • @ConditionalOnBean
  • @ConditionalOnMissingBean
  • @ConditionalOnProperty
    在这里插入图片描述

4. 新建spring.factories

我们看到源码里自动配置,就是从这个文件获取加载,所以我们模仿这新建一个,这样就可以扫描加入容器中!!

在这里插入图片描述

如果是springboot2.7以上就是:
文件夹名称:META-INF.spring
文件名称:org.springframework.boot.autoconfigure.AutoConfiguration.imports

在这里插入图片描述
里面直接写全类名即可!

5. 打包

先把spring-boot-autoconfigure打包到本地库,在打包spring-boot-starter,顺序一定要有,不然找不到前者的包!!

在这里插入图片描述

六、测试

我们那一个新项目进行测试,新项目小编就不带大家建了!

1. 导入咱们的starter依赖

<dependency>
    <groupId>com.wang</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

2. 添加配置文件

wang:
 name:
  prefix: hello
  suffix: 886

在这里插入图片描述

3. 新建controller测试类

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private HelloService helloService;

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

        return helloService.HelloWord("tom");
    }
}

4. 测试访问

成功访问,不过中文是有乱码的,小编找不到解决方法,有懂的还请留言告知!!
主流程通了就行,慢慢理解了自动配置的魅力!
总流程应该就是这样的:

引入starter --- xxxAutoConfiguration --- 容器中放入组件 ---- 绑定xxxProperties ---- 配置项

在这里插入图片描述
中文是乱码,可能是servlet没有吧,有懂的可以留言告诉小编方案,谢谢大家!!

在这里插入图片描述

七、总结

一看会就,一动手就废!大家还是要做自己实操,不要眼高手低,这样才会有收获,根本就是约定大于配置+SPI发现机制
还有就是一些经常出现在源码里的注解,大家记住就可以自己写starter了!

可以看下一小编的微信公众号,和网站文章首发看,欢迎关注!!

点击访问!小编自己的网站,里面也是有很多好的文章哦!

标签:springboot,自定义,spring,配置,boot,autoconfigure,org,starter
From: https://www.cnblogs.com/wang1221/p/16808653.html

相关文章

  • SpringBoot+MybatisPlus--使用
    1、在entity包下面创建数据实体类,添加注解@Data,如果和数据库名字不一样的话,还需要+@TableField注解。字段名字不一样也需要添加此注解@TableName(value="user")publi......
  • IOC--DI--自定义容器
    publicclassXXXContainer:IXXXContainer{//ContainerDicationary保存抽象与细节的映射类型privateDictionary<string,Type>XXXContainerDicationa......
  • JavaScript学习--String对象,自定义对象,window对象
    String对象定义:var变量名=newString(s);varstr=newString("hello");var变量名=s;           varstr="hello";属性:length字符串长度方法:c......
  • SpringBoot对接口请求参数(@RequestBody 和 @ Request Param)进行解密过滤
      /***@Description:拦截所有请求过滤器,并将请求类型是HttpServletRequest类型的请求替换为自定义*/@javax.servlet.annotation.WebFilter(filterName="Web......
  • SpringBoot+MybatisPlus--文件上传
    文件上传时,对页面的form表单有如下要求: 采用post方式提交数据   method="post"采用multipart格式上传文件  enctype="multipart/form-data"使用inp......
  • 手写自定义springboot-starter,感受框架的魅力和原理
    一、前言Springboot的自动配置原理,面试中经常问到,一直看也记不住,不如手写一个starter,加深一下记忆。看了之后发现大部分的starter都是这个原理,实践才会记忆深刻。核心思......
  • Springboot之@Transactional事务注解原理详解
    @Transactional注解的逻辑是通过动态代理来实现的,而生成这个动态代理类分成了两步:1、向spring容器注册事务相关的切面逻辑2、根据切面逻辑生成动态代理下面围绕这两点来看......
  • springboot 常用的注解,解决面试
    一: ComponentScan :作用扫描二: MapperScan :扫描mapper 三: @SpringBootApplication组合注解四: @EnableAutoConfiguration开启自动配置的功能五: @AutoConfigurat......
  • Springboot项目的全局异常处理类
    在controller的同级目录exception下新建一个JavaClass文件,命名为GlobalExceptionHandler,内容如下packagecn.smxy.stest2022101601.exception;importorg.springframe......
  • springBoot 总结
        这是标准创建boot工程的方式 注意这里使用的是阿里云的url  https://start.aliyun.com/修改服务器端口  自动提示功能消失解决方案    ......