SpringBootStarter的定义方式
定义AutoConfiguration
一. 常用注解
1. Configuration
用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
和xml配置一样,可以配置Bean的生命周期中的各个方法。
1 |
问题1:加了Configuration后,怎么将想要的Bean加载到应用的Spring容器中呢?
- 可以想想之前xml的bean配置文件怎么加载的。
1 | public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable { |
也就是在初始化以上各个ApplicationContext的时候,会加载指定的Configuration, 不管是xml还是注解方式的。
那Configuration配置的Bean的加载方式就是可以通过AnnotationConfigApplicationContext。
ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
问题2: Configuration的配置类在做一些组件的时候怎么定义,来实现组件的灵活性
这个问题如果了解一些初始化ApplicationContext的时候对Configuration的识别加载流程可能更容易理解。TODO.
另外,在@configuration中还可以引入其它注解配置
1 |
主要作用理解为是将相关的Bean加载到Spring容器。
2. EnableConfigurationProperties
@EnableConfigurationProperties注解的作用是:使使用 @ConfigurationProperties 注解的类生效。
如果一个配置类只配置@ConfigurationProperties注解,而没有使用@Component,那么在IOC容器中是获取不到properties 配置文件转化的bean。
@EnableConfigurationProperties 相当于把使用 @ConfigurationProperties 的类进行了一次注入。
当@EnableConfigurationProperties注解应用到@Configuration时, 任何被@ConfigurationProperties注解的beans将自动被Environment属性配置。 这种风格的配置特别适合与SpringApplication的外部YAML配置进行配合使用。
感觉和@Component的功能类似。将属性配置类注入到容器。
3. Conditional
Spring4推出了@Conditional注解,方便程序根据当前环境或者容器情况来动态注入bean.
继@Conditional注解后,又基于此注解推出了很多派生注解,比如@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnExpression、@ConditionalOnClass……实现动态注入bean
ConditionalOnClass 自动配置的重要支撑之一。判断当前classpath下是否存在指定类,若是则将当前的配置装载入spring容器。
但这个还不会熟练使用。只是理解了大概是这个意思。
1 |
|
如果classpath存在JsonRedisTemplate的情况下,则将LinkWhiteListRedisOps装载到spring容器。
4. ConditionalXXXX
- @ConditionalOnBean 当指定一个Bean存在是,才创建当前这个Bean
- @ConditionalOnMissingBean 当指定Bean不存在是,才创建这个Bean.
- @ConditionalOnProperty来控制Configuration是否生效
Class的存在与否作为条件。
从使用来看,和前面基本上没有太大的区别,无非就是将bean换成了class;这样就可以避免因为Class Not Found导致的编译异常了。
如提供了一个bean名为RedisOperBean,用于封装redis相关的操作;但是我这个bean需要依赖restTemplate这个bean,只有当应用引入了redis的相关依赖,并存在RestTemplate这个bean的时候,我这个bean才会生效.1
2
3
4
5
6
7
8
public class RedisOperBean {
private final RedisTemplate redisTemplate;
public RedisOperBean(RedisTemplate redisTemplate) {
// ...
}
}
springboot注解丰富,我们可以利用好这些注解来实现我们自定义的starter配置,减少硬编码的校验,降低组件间的耦合性!!!
二. 两种方式集成方式
主动生效和被动生效
从使用者的角度。
1. 主动生效
使用@Import注解。主动声明启用该starter才生效。比如加到我们的启动来,或者将该注解标记到你自定义的@Enable注解上。
1 |
|
2. 被动生效
在starter组件集成入SpringBoot应用时,就已经被应用捕捉到。类似java的SPI机制。
新建 META-INF/spring.factories文件。
写入AutoConfiguration全限定名。
1 | # AutoConfiguration |
3. 优缺点
主动生效的方式需要在使用的项目中手动指定,enable. 也属于硬编码。而相对被动生效。我们可以通过配置来实现组件的生效。
被动生效虽然可以通过配置来控制组件生效,但AutoConfiguration中配置的一些组件对象会实例到容器。
比如redis连接,不管是否生效,他都会在实例化的时候连接默认的redis.如果不适用,实例化就是有些浪费。
三.命名规范
Spring官方Starter通常命名为spring-boot-starter-{name}如 spring-boot-starter-web
Spring官方建议非官方Starter命名应遵循{name}-spring-boot-starter的格式, 如mybatis-spring-boot-starter。