第一篇:SpringIOC源码分析之容器创建前期的准备工作

SpringIOC源码分析之容器创建前期的准备工作

第一节:This()方法

AnnotationConfigApplicationContext 是spring 3.0以后引入的类,用于处理spring注解,可以理解为spring上下文

AnnotationConfigApplicationContext ctx = new    AnnotationConfigApplicationContext(AnswerConfig.class);

AnnotationConfigApplicationContext继承了GenericApplicationContext,而GenericApplicationContext实现了BeanDefinitionRegistry
AnnotationConfigApplicationContext继承关系

进入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都做了什么。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定义读取器)注册配置类。
到这里我们算是把容器创建前期的准备工作分析完了,下一篇我们来看看容器初始化的全过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值