SpringBoot——自定义自动配置与起步依赖

SpringBoot为我们提供了灵活强大的自动配置与起步依赖功能,接下来我们参考其实现原理,实现专属于我们自己的自动配置与起步依赖。

不仅如此,我们对其稍作修改,让它适用于非SpringBoot环境,甚至是低版本的Spring Framework环境

1自动配置

在编写自己的自动配置之前,我们先来看一下SpringBoot自动配置类的实现原理。

SpringBoot可以根据CLASSPATH、配置项等条件自动进行常规配置,省去了我们自己手动把一模一样的配置复制来复制去的麻烦。这样大大提升了开发效率!

在这之前,我们已经看到过@SpringBootApplication注解了,查看这个注解,可以发现它上面添加了一个@EnableAutoConfiguration,基于这个注解就可以开启自动配置功能。

这两个注解上都有exclude属性,我们可以在其中排除一些不想启用的自动配置类。

如果不想启用自动配置功能,也可以在配置文件中配置spring.boot.enableautoconfiguration=false,关闭该功能。

1.1自动配置的实现原理

自动配置类其实就是添加了@Configuration的普通Java配置类,它利用Spring Framework 4.0加入的条件注解@Conditional来实现“根据特定条件启用相关配置类”,注解中传入的Condition类就是不同条件的判断逻辑。SpringBoot内置了很多条件注解,如下表所示:

条件注解 生效条件
@ConditionalOnBean 存在特定名称、特定类型、特定泛型参数或带有特定注解的Bean
@ConditionalOnMissingBean 与前者相反,不存在特定的Bean
@ConditionalOnClass 存在特定的类
@ConditionalOnMissingClass 与前者相反,不存在特定类
@ConditionalOnCloudPlatform 运行在特定的云平台上,截止2.6.3版本,代表云平台的枚举类支持无云平台,可以通过spring.main.cloud-platform配置强制使用的云平台
@ConditionalOnExpression 指定的SpEL表达式为真
@ConditionalOnJava 运行在满足条件的Java上,可以比指定版本新,也可以比指定版本旧
@ConditionalOnJndi 指定的JNDI位置必须存在一个,如没有指定,则需要存在InitalContext
@ConditionalOnProperty 属性值满足特定条件,比如给定的属性值都不能为false
@ConditionalOnResource 存在特定资源
@ConditionalOnSingleCandidate 当前上下文中,特定类型的Bean有且仅有一个
@ConditionalOnWarDeployment 应用程序是通过传统的War方式部署的,而非内嵌容器
@ConditionalOnWebApplication 应用程序是一个Web应用程序
@ConditionalOnNotWebApplication 与前者相反,应用程序不是一个Web应用程序

更多如图所示,就不一一列举了:

以@ConditionalOnClass注解为例,它的定义如下所示,@Target指明该注解可用于类型和方法定义,@Retention指明注解的信息在运行时也能获取到,而其中最关键的就是OnClassCondition条件类,里面是具体的条件计算逻辑:

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass { /**
* The classes that must be present. Since this annotation is parsed by loading class
* bytecode, it is safe to specify classes here that may ultimately not be on the
* classpath, only if this annotation is directly on the affected component and
* <b>not</b> if this annotation is used as a composed, meta-annotation. In order to
* use this annotation as a meta-annotation, only use the {@link #name} attribute.
* @return the classes that must be present
*/
Class<?>[] value() default {}; /**
* The classes names that must be present.
* @return the class names that must be present.
*/
String[] name() default {}; }

了解了条件注解后,再来看看它们是如何与配置类结合使用的。以JdbcTemplateAutoConfiguration为例:


@AutoConfiguration(after = DataSourceAutoConfiguration.class)
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(JdbcProperties.class)
@Import({ DatabaseInitializationDependencyConfigurer.class, JdbcTemplateConfiguration.class,
NamedParameterJdbcTemplateConfiguration.class })
public class JdbcTemplateAutoConfiguration {
}

可以看到这个配置类的生效条件是存在DataSource和JdbcTemplate类,且在上下文中只能有一个DataSource。此外,这个自动配置需要在DataSourceAutoConfiguration之后再配置(可以用@AutoConfigureBefore、@AutoConfigureAfter和@AutoConfigureOrder来控制自动配置的顺序)

2编写自已的自动配置

根据上面的描述,我们很容易想到,要编写自己的自动配置,只需要以下三个步骤:

(1)编写常规的配置类

(2)为配置类增加生效条件与顺序

(3)在/META-INF/spring.factories文件中添加自动配置类

2.1创建项目

在Spring Initializr中,创建一个Maven工程,添加如下依赖:

    <dependencies>
<!-- 添加自动配置所使用的包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- 用户在写配置文件时,会有提示效果 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

2.2编写一个简单的MyAutoConfigure类和配置类Bean

编写一个简单的MyAutoConfigure类,上面增加了@Configuration注解,表示这是一个配置类,这个配置类的生效条件是myconfig.ready属性的值为true,除此之外的值或者不存在该属性时MyAutoConfigure都不会生效。

/**
* TODO 1、编写配置类并指定文件
*
* @author ss_419
* @version 1.0
* @date 2023/3/17 21:24
*/
@Configuration @EnableConfigurationProperties(CommonBean.class)
@ConditionalOnProperty(name = "myconfig.ready",havingValue = "true")
public class MyAutoConfigure {
}
/**
* TODO 2、创建配置类Bean
*
* @author ss_419
* @version 1.0
* @date 2023/3/17 22:40
*/
@ConfigurationProperties("myconfigbean")
@Data
public class MyConfigBean {
private boolean ready;
private String info;
}

2.3配置spring.factories文件

为了让SpringBoot能找到我们写的这个配置类,我们需要在src/resources目录中创建META-INF/spring.factories文件,其内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.pp.myspringbootstart.beans.MyAutoConfigure

2.4测试自动配置是否生效

@SpringBootTest
public class MyConfigurationEnableTest { @Autowired
private ApplicationContext applicationContext; @Test
void testPropertiesBeanAvailableTest() throws Exception {
assertNotNull(applicationContext.getBean(MyConfigBean.class));
assertTrue(applicationContext.containsBean("org.pp.myspringbootstart.beans.MyConfigBean"));
} @Test
void testPropertyValues(){
MyConfigBean bean = applicationContext.getBean(MyConfigBean.class);
assertTrue(bean.isReady());
assertEquals("hello", bean.getInfo());
}
}

SpringBoot——自定义自动配置与起步依赖的更多相关文章

  1. SpringBoot入门(二)——起步依赖

    本文来自网易云社区 在前一篇我们通过简单几步操作就生成了一个可以直接运行的Web程序,这是因为SpringBoot代替我们做了许多工作,概括来讲可以分为起步依赖和自动配置.这一篇先来看看起步依赖. 项 ...

  2. 面试题: SpringBoot 的自动配置原理

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 3.Spring Boot 的自动配置原理 package com.mmall; import org. ...

  3. Spring boot运行原理-自定义自动配置类

    在前面SpringBoot的文章中介绍了SpringBoot的基本配置,今天我们将给大家讲一讲SpringBoot的运行原理,然后根据原理我们自定义一个starter pom. 本章对于后续继续学习S ...

  4. 关于SpringBoot的自动配置和启动过程

    一.简介 Spring Boot简化了Spring应用的开发,采用约定大于配置的思想,去繁从简,很方便就能构建一个独立的.产品级别的应用. 1.传统J2EE开发的缺点 开发笨重.配置繁多复杂.开发效率 ...

  5. Springboot MVC 自动配置

    Springboot MVC 自动配置 官方文档阅读 https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#w ...

  6. SpringBoot的自动配置

    1.根据条件来装配bean,SpringBoot的自动配置,根据条件进行自动配置. 首先创建一个接口,如下所示: package com.bie.encoding; /** * * @Descript ...

  7. springboot(六)自动配置原理和@Conditional

    官方参考的配置属性:https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#common-appl ...

  8. springboot mvc自动配置(一)自动配置DispatcherServlet和DispatcherServletRegistry

    所有文章 https://www.cnblogs.com/lay2017/p/11775787.html 正文 springboot的自动配置基于SPI机制,实现自动配置的核心要点就是添加一个自动配置 ...

  9. springboot mvc自动配置(三)初始化mvc的组件

    所有文章 https://www.cnblogs.com/lay2017/p/11775787.html 正文 在springboot mvc自动配置的时候,获得了DispatcherServlet和 ...

  10. spring-boot spring-MVC自动配置

    Spring MVC auto-configuration Spring Boot 自动配置好了SpringMVC 以下是SpringBoot对SpringMVC的默认配置:==(WebMvcAuto ...

随机推荐

  1. Jmeter的简单配置和使用

    对于测试大佬来说,最常见的压测工具莫过于Apache旗下的 JMeter . 那么测试大佬经常使用,对于我们后端开发者来说,也是属于必备的一个技能. 接下来咱们就一起简单的配置一下烫手的jmeter ...

  2. 前端使用JSEncrypt进行加密和解密

    下载链接:https://www.bootcdn.cn/jsencrypt/ 使用方法: 1.引入jsencrypt 2.使用方法 // 加密公钥 const key = `xxxxxx`; func ...

  3. Day09-参数+递归

    参数+递归 一.命令行传参 有时候你希望运行一个程序时候再传递给它消息.这要靠传递命令行参数给main()函数实现 public class CommandLine{ public static vo ...

  4. 笔记:vue.nextTick()方法的使用详解

    vue.nextTick定义: 在下次DOM更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的DOM. 简单理解:数据更新了,在dom渲染后立即执行该函数 举例 注意:Vue实 ...

  5. SaaS、PaaS、IaaS的区别

    我们从SaaS.PaaS.IaaS的定义.工业应用以及具体案例几方面来介绍他们之间的区别 一.定义层面的区别 SaaS.PaaS.IaaS简单的说都属于云计算服务,也就是云计算+服务. 我们对于云计算 ...

  6. redis远程连接错误SocketTimeoutException: connect timed out

    redis远程连接错误SocketTimeoutException: connect timed out 解决方案: 编辑redis.conf文件(建议将其 先备份 编辑备份文件 启动redis服务时 ...

  7. 使用idea从零编写SpringCloud项目-Ribbo

    git:https://github.com/bmdcheng/product_server git:https://github.com/bmdcheng/order_server 1.需要创建两个 ...

  8. Ubuntu系统设置普通用户最大文件打开数

    背景: Elasticsearch启动报错: ERROR:  bootstrap checks failedmax file descriptors [4096] for elasticsearch ...

  9. 港湾云服务器 香港新世界 节点 centos7.7 64 部署java项目

    开通云服务器 使用Xshell远程登录 XFTP连接服务器查看文件(这个步骤可有可无) yum安装jdk 在linux上使用yum安装是非常粗暴无脑的,但仍然有需要注意的点,不然会掉坑里.这里说一下步 ...

  10. MySQL 日期相关

    NOW() 返回当前的日期和时间 CURDATE() 返回当前的日期 CURTIME() 返回当前的时间 DATE() 提取日期或日期/时间表达式的日期部分 EXTRACT() 返回日期/时间按的单独 ...