SpringIOC源码分析之容器创建前期的准备工作
第一节:This()方法
AnnotationConfigApplicationContext 是spring 3.0以后引入的类,用于处理spring注解,可以理解为spring上下文
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AnswerConfig.class);
AnnotationConfigApplicationContext继承了GenericApplicationContext,而GenericApplicationContext实现了BeanDefinitionRegistry
进入AnnotationConfigApplicationContext,跟进这个this来看看具体的实现逻辑
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
this调用自身无参构造方法(下边这两行代码就是本篇文章所讲解的)
public AnnotationConfigApplicationContext() {
//一、为bean定义读取器赋值
this.reader = new AnnotatedBeanDefinitionReader(this);
//二、创建类路径下的bean定义扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
1>bean定义读取器赋值
通过代码可以看出这里的 AnnotatedBeanDefinitionReader是一个读取注解的Bean读取器,这里将this传了进去
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
//getOrCreateEnvironment:该方法目的是创建一个环境对象,并且根据环境类型,自动判断是创建web环境对象,还是标准非web环境对象
this(registry, getOrCreateEnvironment(registry));
}
再次点击this进入
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.beanNameGenerator = new AnnotationBeanNameGenerator();
this.scopeMetadataResolver = new AnnotationScopeMetadataResolver();
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
//着重讲解 1.1
//创建一个条件计算器对象
this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null);
//着重讲解 1.2
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
分析以上代码可以得知,这里将AnnotationConfigApplicationContext(上边方法的入参BeanDefinitionRegistrt就是AnnotationConfigApplicationContext)注册为管理BeanDefinition的BeanDefinitionRegistry,也就是说,spring中bean的管理完全交给了AnnotationConfigApplicationContext。
这里注意有人会疑惑上边代码最后两行行是干啥的,我们不妨点进去看看
1.1
进入ConditionEvaluator,看看具体逻辑
//创建一个条件计算器对象
public ConditionContextImpl(BeanDefinitionRegistry registry, Environment environment, ResourceLoader resourceLoader) {
//初始条件计算器的bean定义注册器
this.registry = registry;
//初始化bean工厂
this.beanFactory = this.deduceBeanFactory(registry);
//为环境对象赋值
this.environment = environment != null ? environment : this.deduceEnvironment(registry);
//为资源加载器赋值
this.resourceLoader = resourceLoader != null ? resourceLoader : this.deduceResourceLoader(registry);
}
1.2
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, (Object)null);
}
上边这行代码的具体实现还是贴出来吧
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source) {
//获取一个IOC容器
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(4);
RootBeanDefinition def;
//注册一个配置类解析器的bean定义(ConfigurationClassPostProcessor)
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
}
//设置AutoWired注解解析器的bean定义信息
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
}
//注册解析@Required注解的处理器
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalRequiredAnnotationProcessor")) {
def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalRequiredAnnotationProcessor"));
}
//检查是否支持JSR250规范,如何支持注册 解析JSR250规范的注解
if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) {
def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor"));
}
//检查是否支持jpa,若支持注册解析jpa规范的注解
if (jpaPresent && !registry.containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")) {
def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName("org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", AnnotationConfigUtils.class.getClassLoader()));
} catch (ClassNotFoundException var6) {
throw new IllegalStateException("Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", var6);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalPersistenceAnnotationProcessor"));
}
//注册解析@EventListener的注解
if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor")) {
def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerProcessor"));
}
if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory")) {
def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerFactory"));
}
return beanDefs;
}
具体的工作就是给容器中加了6个处理器,如下:
1:bean名称为org.springframework.context.annotation.internalConfigurationAnnotationProcessor的ConfigurationClassPostProcessor。
ConfigurationClassPostProcessor是一个BeanFactory和BeanDefinitionRegistry处理器,BeanDefinitionRegistry处理方法能处理@Configuration等注解。ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()方法内部处理@Configuration,@Import,@ImportResource和类内部的@Bean。
ConfigurationClassPostProcessor类继承了BeanDefinitionRegistryPostProcessor。BeanDefinitionRegistryPostProcessor类继承了BeanFactoryPostProcessor。通过BeanDefinitionRegistryPostProcessor可以创建一个特别后置处理器来将BeanDefinition添加到BeanDefinitionRegistry中。它和BeanPostProcessor不同,BeanPostProcessor只是在Bean初始化的时候有个钩子让我们加入一些自定义操作;而BeanDefinitionRegistryPostProcessor可以让我们在BeanDefinition中添加一些自定义操作。在Mybatis与Spring的整合中,就利用到了BeanDefinitionRegistryPostProcessor来对Mapper的BeanDefinition进行了后置的自定义处理。
2:bean名称为org.springframework.context.annotation.internalAutowiredAnnotationProcessor的AutowiredAnnotationBeanPostProcessor。AutowiredAnnotationBeanPostProcessor是一个BeanPostProcessor,注意BeanPostProcessor和BeanFactoryPostProcessor的区别。AutowiredAnnotationBeanPostProcessor是用来处理@Autowired注解和@Value注解的。
3:bean名称为org.springframework.context.annotation.internalRequiredAnnotationProcessor的RequiredAnnotationBeanPostProcessor。这是用来处理@Required注解。
4:bean名称为org.springframework.context.annotation.internalCommonAnnotationProcessor的CommonAnnotationBeanPostProcessor。CommonAnnotationBeanPostProcessor提供对JSR-250规范注解的支持@javax.annotation.Resource、@javax.annotation.PostConstruct和@javax.annotation.PreDestroy等的支持。
5:bean名称为org.springframework.context.annotation.internalPersistenceAnnotationProcessor的PersistenceAnnotationBeanPostProcessor。EventListenerMethodProcessor提供@PersistenceContext的支持。
6:bean名称为org.springframework.context.annotation.internalEventListenerProcessor的EventListenerMethodProcessor。EventListenerMethodProcessor提供@ EventListener 的支持。@ EventListener实在spring4.2之后出现的,可以在一个Bean的方法上使用@EventListener注解来自动注册一个ApplicationListener
自此,AnnotatedBeanDefinitionReader初始化完毕。总结一下,AnnotatedBeanDefinitionReade读取器用来加载class类型的配置,在它初始化的时候,会预先注册一些BeanPostProcessor和BeanFactoryPostProcessor,这些处理器会在接下来的spring初始化流程中被调用
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~完美的分割线
2>创建类路径下的bean定义扫描器
接下来我们分析下初始化ClassPathBeanDefinitionScanner都做了什么。继承了 ClassPathScanningCandidateComponentProvider。registerDefaultFilters() 就是 ClassPathScanningCandidateComponentProvider中的方法
一直进入this方法最后看到它的实现逻辑
/**
* 全局变量
* 这两个对象在ClassPathScanningCandidateComponentProvider这个类执行findCandidateComponents(String basePackage)方法,也就是扫描给定类路径的包的时候,会充当过滤规则,includeFilters中的就是满足过滤规则的,excludeFilters则是不满足过滤规则的。
*/
private final List<TypeFilter> includeFilters;
private final List<TypeFilter> excludeFilters;
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, ResourceLoader resourceLoader) {
this.beanDefinitionDefaults = new BeanDefinitionDefaults();
this.beanNameGenerator = new AnnotationBeanNameGenerator();
this.scopeMetadataResolver = new AnnotationScopeMetadataResolver();
this.includeAnnotationConfig = true;
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
//useDefaultFilters = true;
if (useDefaultFilters) {
//2.1 使用默认的扫描规则
this.registerDefaultFilters();
}
//2.2 设置环境
this.setEnvironment(environment);
//2.3 设置资源加载器
this.setResourceLoader(resourceLoader);
}
2.1 this.registerDefaultFilters();
该方法为includeFilters加入了三个TypeFilter,具体来说,是三个AnnotationTypeFilter,它是TypeFilter的一个实现,用于判断类的注解修饰型是否满足要求。从中可知通过 @Component、@javax.annotation.ManagedBean 和 @javax.inject.Named 以及标记了这些 Annotation 的新 Annotation 注解过的 Java 对象即为 Spring 框架通过 Annotation 配置的默认规则。注意@service,@controller等都继承了@component,是符合规则的
protected void registerDefaultFilters() {
//@Compent @Service @Repository @Controller @Aspectj
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
//jsr250规范的组件
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.annotation.ManagedBean", cl), false));
this.logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
} catch (ClassNotFoundException var4) {
}
try {
//可以支持jsr330的注解
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.inject.Named", cl), false));
this.logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
} catch (ClassNotFoundException var3) {
}
}
上边的方法看起来是挺好理解的,然而容器启动的时候会过滤掉一些暂时不需要初始化的对象,还记得这个类中定义的两个全局变量includeFilters和excludeFilters吗,ClassPathScanningCandidateComponentProvider这个类执行findCandidateComponents(String basePackage)方法的时候这两个变量就是来充当规则的,接下俩我们着重看看这个方法
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
LinkedHashSet candidates = new LinkedHashSet();
try {
String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//获取到文件内容,文件和path(class文件)
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
boolean traceEnabled = this.logger.isTraceEnabled();
boolean debugEnabled = this.logger.isDebugEnabled();
Resource[] var7 = resources;
int var8 = resources.length;
for(int var9 = 0; var9 < var8; ++var9) {
Resource resource = var7[var9];
if (traceEnabled) {
this.logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
//读取源信息
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
//过滤匹配排除excludeFilters排除过滤器(可以没有),包含includeFilter中的包含过滤器(至少包含一个)
//2.1.1 下文单拿出来讲解
if (this.isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
//判断是否是合格的bean定义
if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) {
if (debugEnabled) {
this.logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
} else if (debugEnabled) {
this.logger.debug("Ignored because not a concrete top-level class: " + resource);
}
} else if (traceEnabled) {
this.logger.trace("Ignored because not matching any filter: " + resource);
}
} catch (Throwable var13) {
throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, var13);
}
} else if (traceEnabled) {
this.logger.trace("Ignored because not readable: " + resource);
}
}
return candidates;
} catch (IOException var14) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", var14);
}
}
上段代码主要干的活儿就是spring根据传进来的basePackage(通常是启动类的位置)来遍历这个路径下的所有class,然后根据excludeFilters排除过滤器(可以没有),包含includeFilter中的包含过滤器(至少包含一个)。此处我们具体看看上边代码2.1.1处的isCandidateComponent方法,实现逻辑如下
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
Iterator var2 = this.excludeFilters.iterator();
TypeFilter tf;
do {
if (!var2.hasNext()) {
var2 = this.includeFilters.iterator();
do {
if (!var2.hasNext()) {
//排除
return false;
}
tf = (TypeFilter)var2.next();
} while(!tf.match(metadataReader, this.metadataReaderFactory));
//如果经过上述代码考验了在此处还需要判断是否是合格的bean定义
//2.1.2具体分析
return this.isConditionMatch(metadataReader);
}
tf = (TypeFilter)var2.next();
} while(!tf.match(metadataReader, this.metadataReaderFactory));
return false;
}
上边代码块的2.1.2处具体逻辑代码如下
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
AnnotationMetadata metadata = beanDefinition.getMetadata();
//独立的非接口非抽象类的普通类,或者@Lookup注解的抽象类
return metadata.isIndependent() && (metadata.isConcrete() || metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()));
}
第二节 register(annotatedClasses)方法
AnnotationConfigApplicationContext默认构造方法我们分析完了,接着我们看看this.register(annotatedClasses);做了什么
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
显而易见,通过上一行代码生成的AnnotatedBeanDefinitionReader(bean定义读取器)注册配置类。
到这里我们算是把容器创建前期的准备工作分析完了,下一篇我们来看看容器初始化的全过程