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. jenkins +docker+python接口自动化之docker下安装jenkins(一)

    1.下载jenkins启动docker服务之后,首先搜索可用的jenkins镜像 docker search jenkins 第一个是官方版本,但是已标明废弃了,让用第二个jenkisn/jenkin ...

  2. Activiti工作流引擎系列-第二篇

    官网案例下载安装实例 { "info": { "_postman_id": "64f2d7ca-8287-4f8d-94ba-1138861877dd ...

  3. ZSTUOJ刷题④:Problem B.--输出双层金字塔

    Problem B: 输出双层金字塔 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 7860  Solved: 5834 Description 输出双层 ...

  4. 关于JDK1.8 java HashMap的tableSizeFor的解析:一个数最近2的幂次数方法

    简介 一个数的最近2的幂次数,是java hashmap初始化方法指定容量里面对容量进行处理采用的方法 1.位运算符号介绍 符号 描述 运算规则 & 与 两个位都为1时,结果才为1 | 或 两 ...

  5. bzoj 3532

    很好的一道题,对理解最小割有很大帮助 首先,不难发现本题与网络流24题中的某一道很类似,我们可以先跑一次dp求出每个节点的LIS,然后拆点,拆出的两点之间连流量为删除的代价的边,剩下的点之间按dp的转 ...

  6. bzoj 3561

    题意:求$\sum_{i=1}^{n}\sum_{j=1}^{n}lcm(i,j)^{gcd(i,j)}$ 神仙题... 首先可能会想到一个转化,就是$lcm(i,j)=\frac{ij}{gcd(i ...

  7. source Insight 的常用设置

    1. 去除^M 的显示 "Options->Preferences->Files", 设置"Default File Format" to &quo ...

  8. Liunx安装Docker

    1.更新yum包到最新 sudo yum update 2.卸载历史Docker,如果没有安装过,则跳过该步 sudo yum remove docker \ docker-client \ dock ...

  9. win 端口占用

    netstat -aon|findstr "8080" 查看端口 TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 11468 TCP 172.27.232 ...

  10. 4组-Beta冲刺-5/5

    一.基本情况 队名:摸鲨鱼小队 组长博客:https://www.cnblogs.com/smallgrape/p/15608986.html github链接:https://github.com/ ...