不学无数——SpringBoot入门Ⅶ

SpringBoot

1.建立本身的Auto-configuration

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

Auto-configuration一般是和starter联系起来的,一个官网提供的小例子展现了如何一步一步建立属于本身的startergit

1.1 理解Auto-configured类

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

你也能够经过浏览SpringBoot-autoConfigure由Spring提供的@Configuration类。web

1.2 Auto-configuration的目录结构

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

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

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

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

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

1.3 Condition注解

SpringBoot利用@Condition注解来肯定是否是要建立Bean实例ide

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

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的开箱即用的观点。

相关文章
相关标签/搜索