不学无数——SpringBoot入门Ⅶ

简介: SpringBoot1.创建自己的Auto-configuration无论是在公司中你想开发自己的一套框架,定制一些东西,或者是在开源网站中分享自己做的一些东西。

SpringBoot

1.创建自己的Auto-configuration

无论是在公司中你想开发自己的一套框架,定制一些东西,或者是在开源网站中分享自己做的一些东西。你可能想要开发属于自己的Auto-configuration。Auto-configuration的类能够捆绑到外部的jar包中,并且被SpringBoot进行使用。例如我们经常使用的@Autowire注解会自动的注入一个实例到Spring的容器中,这时我们被注入进来的类必须有个注解进行标注,例如:@Service、@Controller等等。但是对于在jar包中的类的话,考虑的需要多一些,例如需要考虑在注入时我会依赖到谁,谁先进行注入等等。

Auto-configuration通常是和starter联系起来的,一个官网提供的小例子展示了如何一步一步创建属于自己的starter

1.1 理解Auto-configured类

在底层代码中,Auto-configured是被@Configuration注解的类实现的。另外@Conditional注解被用来限制什么时候Auto-configured应该被应用。通常来说,Auto-configured的类使用@ConditionalOnClass@ConditionalOnMissingBean这两个注解,这是为了确保 auto-configuration 只在一些相关的类生效以后才会加载@Configuration类。

你也可以通过浏览SpringBoot-autoConfigure由Spring提供的@Configuration类。

1.2 Auto-configuration的目录结构

SpringBoot会检查所有jar包中的META-INF/spring.factories文件,在这个文件中应该列出了key是EnableAutoConfigurationvalue是想要配置的类,例如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration

当然也可以使用@AutoConfigureAfter@AutoConfigureBefore两个注解进行标识想要哪个类进行先加载。例如想要提供一个特定的web配置,那么你的类应该在WebMvcAutoConfiguration之后加载。

如何想要auto-configurations的类进行顺序的加载,那么可以使用@AutoConfigureOrder注解进行排序。

Auto-configurations仅仅能够被这种方式进行加载,实际上,他们不会被包扫描进行加载。

1.3 Condition注解

SpringBoot利用@Condition注解来确定是不是要创建Bean实例

在所开发的对外封装jar包中可能会使用一个或者多个的@Condition注解在自动配置的类中。@ConditionalOnMissingBean注解会覆盖掉你的默认配置。

SpringBoot包括许多的@Conditional的注解,你能够重复使用它在类中或者单独的@Bean方法上。这些注解包括

  • Class Conditions
  • Bean Conditions
  • Property Conditions
  • Resource Conditions
  • Web Application Conditions

1.3.1 Class Conditions

  • @ConditionalOnClass: 某个class位于类路径上,才会实例化一个Bean。该注解的参数对应的类必须存在,否则不解析该注解修饰的配置类。这个很有用的,比如不同的jar包之间有依赖,如果依赖的类不存在的话,那么就会直接跳过,不会报错。
  • @ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean。该注解表示,如果存在它修饰的类的bean,则不需要再创建这个bean,可以给该注解传入参数例如@ConditionOnMissingBean(name = "example"),这个表示如果name为“example”的bean存在,这该注解修饰的代码块不执行

1.3.2 Bean Conditions

  • @ConditionalOnBean:仅仅在当前上下文中存在某个对象时,才会实例化一个Bean
  • @ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean

举例如下:

@Configuration
public class MyAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyService myService() { ... }

}

1.3.3 Property Conditions

  • @ConditionalOnProperty:这个注解能够控制某个configuration是否生效。具体操作是通过其两个属性name以及havingValue来实现的,其中name用来从application.properties中读取某个属性值,如果该值为空,则返回false;如果值不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true;否则返回false。如果返回值为false,则该configuration不生效;为true则生效。

1.3.4 Resource Conditions

  • @ConditionalOnResource注解允许只有在特定资源出现时配置才会生效。资源可以使用常见的Spring约定命名,例如file:/home/user/test.dat。

1.3.5 Web Application Conditions

  • @ConditionalOnWebApplication和@ConditionalOnNotWebApplication两个注解会根据应用是否为一个Web应用而使配置生效。

2. 一个自动配置的小例子

2.1 创建一个接受配置属性的类

如果对于如何用java实体类进行接受配置文件的属性不明白的,可以参考我的文章不学无数——SpringBoot入门Ⅲ,里面有详细讲解。


@ConfigurationProperties("acme")
@Validated
public class AcmeProperties {
    private boolean enabled;
    @NotNull(message = "不能weikong ")
    private String remoteAddress;

    public boolean isEnabled() { return enabled; }

    public void setEnabled(boolean enabled) { this.enabled=enabled; }

    public String getRemoteAddress() { return remoteAddress; }

    public void setRemoteAddress(String remoteAddress) { this.remoteAddress=remoteAddress; }

}

2.2 创建配置属性的类

这里只是简单的举个配置属性的例子: 例如在这里可以进行配置数据库的事务。然后在动态创建数据源的时候可以判断这个类是否创建然后创建数据源。

即这个类是一个作为判断依据的类

public class AcmeService {
    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "AcmeService{" +
                "msg='" + msg + '\'' +
                '}';
    }
}

2.3 创建自动配置的类

@ConditionalOnClass该注解在之前已经讲过,这里的意思就是AcmeService类在路径中已经存在以后才会解析配置类。@ConditionalOnMissingBean方法上的注解我们上面也解释过了,在这的意思就是在容器中没有AcmeService对象时才会实例化此Bean。


@Configuration
@ConditionalOnClass(AcmeService.class)
@EnableConfigurationProperties(AcmeProperties.class)
public class AcmeAutoConfiguration {

    private final AcmeProperties acmeProperties;

    public AcmeAutoConfiguration(AcmeProperties acmeProperties) {
        this.acmeProperties = acmeProperties;
    }

    @Bean
    @ConditionalOnMissingBean(AcmeService.class)
    public AcmeService getAcmeService(){
        AcmeService acmeService=new AcmeService();
        acmeService.setMsg(acmeProperties.toString());
        return acmeService;
    }
}

2.4 注册配置

resources-META-INF文件夹下创建spring.factories文件,里面写入自动配置类的路径

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.FirstSpringBoot.Configuration.AcmeAutoConfiguration

2.5 开始使用

因为我们创建的自动配置是要供别人使用的,只对外提供配置的属性值,所以我们将我们写的自动配置的一系列类进行打jar包,另一个项目引用过后只需要在配置文件中配置我们对外提供的配置属性进行配置以后就可以使用我们自动配置类提供的功能了。这也正符合了SpringBoot的开箱即用的观点。

相关文章
|
4月前
|
Java Docker 容器
美团大牛精心整理SpringBoot学习笔记,从Web入门到系统架构
近期慢慢复工,为了准备面试,各路码友们都开始磨拳擦脚,背面试题、知识点。小编最近得一良友赠送了一份关于SpringBoot的学习笔记,简直不要好用,理论解析言简意赅,每一步操作都有图片展示。这么好的东西肯定不能私藏,为了感谢大家在2019年里的支持,我现在将这份笔记赠送给大家,祝大家前程似锦,Offer不断!
|
6月前
|
Java Go 开发者
Spring Boot 简介与入门
Spring Boot 简介与入门
46 0
|
3月前
|
Java API
分布式锁【分布式锁概述、业务介绍、创建SpringBoot项目】(一)-全面详解(学习总结---从入门到深化)
分布式锁【分布式锁概述、业务介绍、创建SpringBoot项目】(一)-全面详解(学习总结---从入门到深化)
21 0
|
8月前
|
NoSQL 前端开发 Java
SpringBoot 开发入门—Springboot基础框架
SpringBoot 开发入门—Springboot基础框架
238 0
|
6月前
|
Java 测试技术
[笔记]Springboot入门《五》之单元测试读取配置
[笔记]Springboot入门《五》之单元测试读取配置
|
8月前
|
Java Docker 容器
美团大牛精心整理SpringBoot学习笔记,从Web入门到系统架构
近期慢慢复工,为了准备面试,各路码友们都开始磨拳擦脚,背面试题、知识点。小编最近得一良友赠送了一份关于SpringBoot的学习笔记,简直不要好用,理论解析言简意赅,每一步操作都有图片展示。这么好的东西肯定不能私藏,为了感谢大家在2023年里的支持,我现在将这份笔记赠送给大家,祝大家前程似锦,Offer不断!
|
8月前
|
Java 关系型数据库 MySQL
Spring Boot入门(二十八) 之 Docker安装数据库
Spring Boot入门(二十八) 之 Docker安装数据库
|
8月前
|
Java 应用服务中间件 Docker
Spring Boot入门(二十七) 之 Docker常用命令
Spring Boot入门(二十七) 之 Docker常用命令
|
8月前
|
Java Linux Docker
Spring Boot入门(二十六) 之 Docker的安装与基本使用
Spring Boot入门(二十六) 之 Docker的安装与基本使用
|
8月前
|
Java Spring
Spring Boot入门(十三) 之 thymeleaf一些常用语法规则
Spring Boot入门(十三) 之 thymeleaf一些常用语法规则

相关实验场景

更多