spring学习笔记(五)自定义spring-boot-starter(1)
在我们开始定义之前我们应该知道springBoot的大致运行原理,我们从springBoot启动类开始。首先我们看下这个注解,@SpringBootApplication,跟进去可以看到如下代码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
......
}
关于自动配置的核心注解就是@EnableAutoConfiguration,我们继续跟踪
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
.......
}
可以看到这个注解的主要作用就是导入了{AutoConfigurationImportSelector.class}这个类,我们跟一下这个类的源码,这里我们直接用debug调试下,我们找到.AutoConfigurationImportSelector下的getCandidateConfigurations方法,在上面打个断点,然后启动我们的应用程序
此时程序会进入到上面这个状态,这也是我们分析的关键,跟进去后可以看到
在这里开始获取自动配置的类,EnableAutoConfiguration,我们继续跟进loadSpringFactories(...)方法
最后会看到如下的代码:
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
到这里就很明显了,我应用程序在启动时,会自动去读"META-INF/spring.factories"文件,并获取其中键为EnableAutoConfiguration的值,并加载。
我们可以找到我们应用程序中对应的这个文件,就在如图所示的位置
实际上,我们的工程中以autoconfigure结尾的大都有这个文件
我们打开文件,可以看到这样的配置信息
这代表我们应用程序需要自动装配的类。下一个问题来了,只要这样配置了,这些AutoConfiguration就一定会自动装配吗?
答案显然是否定的。
我们就以其中一个配置类为例,比如上图中的AopAutoConfiguration,我们在工程中搜索这个类,可以看到
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,
AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {......}
可以看到@conditionalxxxx注解,这其实就是条件装配,条件装配的原理很简单,我就不多赘述了,上面的@ConditionalOnClass其实就代表要在这些类{ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,AnnotatedElement.class}存在的情况下才会加载这个配置类
有关条件配置,我在下篇文章跟自定义spring-boot-starter一起写出来
有什么不对的希望大家多多指正~