(一)SpringBoot源码学习笔记

1、SpringBoot容器启动

版本:
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>

1.1.启动容器方法

ConfigurableApplicationContext context = SpringApplication.run(PortalApplication.class, args);

1.2.SpringApplication构造

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
        //推断出是servlet容器还是reactive容器
        this.webApplicationType = deduceWebApplicationType();
        //设置在应用初始化时的对象
        setInitializers((Collection) getSpringFactoriesInstances(
                ApplicationContextInitializer.class));
        //设置应用的监听器
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        //推断main方法
        this.mainApplicationClass = deduceMainApplicationClass();
    }
判断容器类型细节
    如果包含org.springframework.web.reactive.DispatcherHandler
    类并且不包含org.springframework.web.servlet.DispatcherServlet
    为reactive服务
    包含
    javax.servlet.Servlet
    org.springframework.web.context.ConfigurableWebApplicationContext    
    类则为serlvet容器

获取springFactoriesInstances的细节
    classpath下的META/spring.factories中配置的各个全路径类名然后
    通过SpringFactoriesLoader.loadFactoryNames(type, classLoader)加载到配置的对应实现类class name
    再使用BeanUtils.instantiateClass(constructor, args)反射创建对象
推断main方法细节
    利用异常中的stackTrace来推断
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
            for (StackTraceElement stackTraceElement : stackTrace) {
                if ("main".equals(stackTraceElement.getMethodName())) {
                    return Class.forName(stackTraceElement.getClassName());
                }
            }

1.3.SpringApplication启动

public ConfigurableApplicationContext run(String... args) {
        //计时器 用来统计启动时间等
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        //从spring.factories中获取应用启动监听器
        //实现的接口SpringApplicationRunListener,通过构造参数传递SpringApplication以及命令行参数
        SpringApplicationRunListeners listeners = getRunListeners(args);
        //启动事件
        listeners.starting();
        try {
            //包装命令行参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            //准备环境变量
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            configureIgnoreBeanInfo(environment);
            //打印banner
            Banner printedBanner = printBanner(environment);
            //根据容器类型构造应用上下文对象
            context = createApplicationContext();
            //从spring.factories中获取对应的SpringBootExceptionReporter并进行实例化
            exceptionReporters = getSpringFactoriesInstances(
                    SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
            //配置应用上下文对象
            prepareContext(context, environment, listeners, applicationArguments,
                    printedBanner);
            //通过refresh来触发对象容器启动
            refreshContext(context);
            afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                        .logStarted(getApplicationLog(), stopWatch);
            }
            listeners.started(context);
            callRunners(context, applicationArguments);
        }
        catch (Throwable ex) {
            handleRunFailure(context, listeners, exceptionReporters, ex);
            throw new IllegalStateException(ex);
        }
        listeners.running(context);
        return context;
    }
环境变量细节

    如果是servlet容器则使用StandardServletEnvironment
    否则使用StandardEnvironment
    也可以自定义一个ConfigurableEnvironment
    参数优先级
    1. 命令行参数
    2. 来自于java:comp/env的JNDI属性
    3. Java系统属性( System.getProperties())
    4. 操作系统环境变量
    5. 只有在random.*里包含的属性会产生一个RandomValuePropertySource
    6. 在打包的jar外的应用程序配置文件( application.properties, 包含YAML和profile变量)
    7. 在打包的jar内的应用程序配置文件( application.properties, 包含YAML和profile变量)
    8. 在@Configuration类上的@PropertySource注解
    9. 默认属性( 使用SpringApplication.setDefaultProperties指定)
    创建的容易对象
    一般
    org.springframework.context.annotation.AnnotationConfigApplicationContext
    web
    org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
    reactive
    org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext

prepareContext细节
    private void prepareContext(ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {
        //给应用上下文设置环境变量
        context.setEnvironment(environment);
        postProcessApplicationContext(context);
        //调用上面设置的初始化时的对象进行initializer.initialize(context);方法调用
        applyInitializers(context);
        listeners.contextPrepared(context);
        if (this.logStartupInfo) {
            logStartupInfo(context.getParent() == null);
            logStartupProfileInfo(context);
        }

        // Add boot specific singleton beans
        context.getBeanFactory().registerSingleton("springApplicationArguments",
                applicationArguments);
        if (printedBanner != null) {
            context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
        }

        // 根据构造时传入的资源进行资源加载
        //可以是类名、包名、或者XML的bean定义资源路径
        Set<Object> sources = getAllSources();
        Assert.notEmpty(sources, "Sources must not be empty");
        //加载资源到context中
        load(context, sources.toArray(new Object[0]));
        listeners.contextLoaded(context);
    }
加载资源细节
    根据应用上下文获取到BeanDefinitionRegistry(用来注册扫描到的bean定义)
    和资源配置信息来构造出BeanDefinitionLoader loader
    然后进行loader.load();加载Bean的定义信息去往BeanDefinitionRegistry中注册

    在loader.load();中如果是class类型的会去读取类上面的注解信息,根据注解来解析相关参数再通过AnnotatedBeanDefinitionReader进行
    将解析到的BeanDefinition注册到context中

2、构造应用上下文

spring boot中如果是普通的web应用会创建AnnotationConfigServletWebServerApplicationContext作为应用上下文对象
AnnotationConfigServletWebServerApplicationContext的构造方法
public AnnotationConfigServletWebServerApplicationContext() {
    //用来处理有spring以及spring支持的ee规范中注解的实现类。
    this.reader = new AnnotatedBeanDefinitionReader(this);
    //用来组件扫描获取BeanDefinition的实现类
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

2.1.接下来查看spring关于注解解析实现

查看AnnotatedBeanDefinitionReader的构造方法
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;
    //@Condition一系列注解实现,用来判断是否满足进行加载处理的条件,不满足则忽略掉不进一步处理。
    //比如在spring boot 的autoconfigure模块中一些自动配置的类都是通过@Condition相关的类来进行判断是否自动配置。
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    //注册用来处理容器中的spring注解的,注解处理器    
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
注解处理器大都是根据spring的xxxPostProcessor来进行实现的。根据注解的性质来决定在对象的哪个阶段进行处理。
下面是registerAnnotationConfigProcessors方法的代码
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {

        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            //设置基于@Order注解或者实现Ordered接口的优先级比较器,用来给多实现的依赖对象排序或者获取对象的优先级
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            //设置用来解析需要依赖注入的属性的解析器
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(4);

        //注册用来处理配置相关注解的默认对象@Configuration、@Import、@PropertySources、@ComponentScans、@ImportResource、@Bean等等
        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
        //注册用来处理依赖注入的处理器。包含构造器注入、方法、fields。。。
        //默认处理的注解有@Autowired @Value @Inject (JSR-330)
        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        //注册验证@Required 的处理器 如果开启验证,而且没有设置注入的对象则抛出BeanInitializationException
        if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
        //实现@PostConstruct @PreDestroy 生命周期方法以及对@Resource @WebServiceRef @EJB 进行依赖注入的的处理器
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
        // 处理JPA相关的注解处理器注册
        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition();
            try {
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                        AnnotationConfigUtils.class.getClassLoader()));
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        //注册用来@EventListener注解标记方法来实现监听通过容器发布的事件的处理器
        //默认是通过ApplicationListenerMethodAdapter 来适配标记方法与ApplicationListener接口。
        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }
        //注册DefaultEventListenerFactory用来创建上面的ApplicationListenerMethodAdapter来协助完成容器事件总线。
        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }

        return beanDefs;
    }
下面的处理器都可以通过往应用上下文中注册对应的BeanDefinition来去覆盖这里的默认处理器。
2.1.1.处理配置相关注解ConfigurationClassPostProcessor的实现细节
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
        PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
        ...
}
查看该类实现的接口可以看到该类实现自BeanDefinitionRegistryPostProcessor
postProcessBeanDefinitionRegistry方法是在所有合适的bean definition都加载完毕后~bean实例化之前时
的一个hook
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

/**
 * Modify the application context's internal bean definition registry after its
 * standard initialization. All regular bean definitions will have been loaded,
 * but no beans will have been instantiated yet. This allows for adding further
 * bean definitions before the next post-processing phase kicks in.
 * @param registry the bean definition registry used by the application context
 * @throws org.springframework.beans.BeansException in case of errors
 */
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

查看ConfigurationClassPostProcessor的实现

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    //不管是否重写了对象的hashCode,只要是同一个对象,都返回相同的hash值
    int registryId = System.identityHashCode(registry);
    if (this.registriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
    }
    //保证只会处理一遍
    if (this.factoriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanFactory already called on this post-processor against " + registry);
    }
    this.registriesPostProcessed.add(registryId);

    processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
    String[] candidateNames = registry.getBeanDefinitionNames();

    for (String beanName : candidateNames) {
        BeanDefinition beanDef = registry.getBeanDefinition(beanName);
        //这里通过设置检查BeanDefinition中的属性来避免重复处理
        if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
                ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
            }
        }
        //检查该BeanDefinition是否符合本处理器处理的范畴,如果符合设置attribute标记防止被重复处理
        else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
            configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
        }
    }

    // Return immediately if no @Configuration classes were found
    if (configCandidates.isEmpty()) {
        return;
    }

    // Sort by previously determined @Order value, if applicable
    configCandidates.sort((bd1, bd2) -> {
        int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
        int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
        return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
    });

    // Detect any custom bean name generation strategy supplied through the enclosing application context
    SingletonBeanRegistry sbr = null;
    if (registry instanceof SingletonBeanRegistry) {
        sbr = (SingletonBeanRegistry) registry;
        if (!this.localBeanNameGeneratorSet) {
            BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
            if (generator != null) {
                this.componentScanBeanNameGenerator = generator;
                this.importBeanNameGenerator = generator;
            }
        }
    }

    if (this.environment == null) {
        this.environment = new StandardEnvironment();
    }

    // Parse each @Configuration class
    // 构造用来解析处理配置相关注解实例
    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    do {
        //开始解析,将根据配置注解解析到对应的配置属性ConfigurationClass
        parser.parse(candidates);
        parser.validate();

        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);

        // Read the model and create bean definitions based on its content
        if (this.reader == null) {
            this.reader = new ConfigurationClassBeanDefinitionReader(
                    registry, this.sourceExtractor, this.resourceLoader, this.environment,
                    this.importBeanNameGenerator, parser.getImportRegistry());
        }
        //根据解析到的配置信息作对应的BeanDefinition注册调用等等处理。
        this.reader.loadBeanDefinitions(configClasses);
        alreadyParsed.addAll(configClasses);

        candidates.clear();
        //由于处理一轮bean的注解信息之后可能会再产生一批新的BeanDefinition因此,这里需要对新产生的那部分继续循环处理
        if (registry.getBeanDefinitionCount() > candidateNames.length) {
            String[] newCandidateNames = registry.getBeanDefinitionNames();
            Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
            Set<String> alreadyParsedClasses = new HashSet<>();
            for (ConfigurationClass configurationClass : alreadyParsed) {
                alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
            }
            for (String candidateName : newCandidateNames) {
                //判断是新增的BeanDefinition 并且是未处理过的 则作为新的一批candidateNames循环处理。
                if (!oldCandidateNames.contains(candidateName)) {
                    BeanDefinition bd = registry.getBeanDefinition(candidateName);
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                            !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                        candidates.add(new BeanDefinitionHolder(bd, candidateName));
                    }
                }
            }
            candidateNames = newCandidateNames;
        }
    }
    while (!candidates.isEmpty());

    // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
    if (sbr != null) {
        if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
            sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
        }
    }

    if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
        // Clear cache in externally provided MetadataReaderFactory; this is a no-op
        // for a shared cache since it'll be cleared by the ApplicationContext.
        ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    }
}
通过上面的代码可以看到,spring中的注解是通过这个处理器,在容器中的BeanDefinition注册完毕~实例化之前通过ConfigurationClassParser
进行循环解析这些包含配置相关注解信息的BeanDefinition,去将注解中配置的一些类,或者通过@Bean注解配置的对象等等生成BeanDefinition注册
到容器中。

下面查看ConfigurationClassParser实现细节,看是怎么实现的注解解析。
parser.parse(candidates);
public void parse(Set<BeanDefinitionHolder> configCandidates) {
        //需要延后处理的ImportSelector
        this.deferredImportSelectors = new LinkedList<>();

        for (BeanDefinitionHolder holder : configCandidates) {
            BeanDefinition bd = holder.getBeanDefinition();
            try {
                //获取BeanDefinition中解析到的注解元数据 然后在下面构造出对应的ConfigurationClass对象
                //基于注解的BeanDefinition
                if (bd instanceof AnnotatedBeanDefinition) {
                    parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
                }
                //基于Class(下面会通过new StandardAnnotationMetadata(clazz, true)去解析类中的注解元数据)
                else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
                    parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
                }
                //基于类名(下面会通过MetadataReader来读取解析类名对应的类中的注解元数据)
                else {
                    parse(bd.getBeanClassName(), holder.getBeanName());
                }
            }
            catch (BeanDefinitionStoreException ex) {
                throw ex;
            }
            catch (Throwable ex) {
                throw new BeanDefinitionStoreException(
                        "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
            }
        }

        processDeferredImportSelectors();
    }
上面主要是想办法从BeanDefinition中获取到注解元数据
下面是处理ConfigurationClass的方法
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
    //实现@Conditional相关的注解,根据注解配置的条件来判断是否满足而后进一步处理
    if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
        return;
    }

    //这部分主要是判断ConfigurationClass是否已经通过其他类导入过了。如果导入过了就直接忽略掉。
    ConfigurationClass existingClass = this.configurationClasses.get(configClass);
    if (existingClass != null) {
        if (configClass.isImported()) {
            if (existingClass.isImported()) {
                existingClass.mergeImportedBy(configClass);
            }
            // Otherwise ignore new imported config class; existing non-imported class overrides it.
            return;
        }
        else {
            // Explicit bean definition found, probably replacing an import.
            // Let's remove the old one and go with the new one.
            this.configurationClasses.remove(configClass);
            this.knownSuperclasses.values().removeIf(configClass::equals);
        }
    }

    // Recursively process the configuration class and its superclass hierarchy.
    //这里的处理是为了实现继承关系doProcessConfigurationClass处理完当前类会获取到父类并返回,
    //这样就可以通过循环处理完整个 当前类->superclass->superclass->...complete
    SourceClass sourceClass = asSourceClass(configClass);
    do {
        sourceClass = doProcessConfigurationClass(configClass, sourceClass);
    }
    while (sourceClass != null);
    //保存处理过的类
    this.configurationClasses.put(configClass, configClass);
}
上面方法主要处理的继承关系层面的问题。具体的处理逻辑在doProcessConfigurationClass方法中
下面查看doProcessConfigurationClass方法的代码
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
        throws IOException {

    //这里先处理内部类的配置类
    // Recursively process any member (nested) classes first
    processMemberClasses(configClass, sourceClass);

    //这里解析@PropertySources注解属性,然后通过PropertySourceFactory构造出对应的PropertySource<?>对象
    //这个主要是用来配置或者拓展容器中environment对象的
    // Process any @PropertySource annotations
    for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
            sourceClass.getMetadata(), PropertySources.class,
            org.springframework.context.annotation.PropertySource.class)) {
        if (this.environment instanceof ConfigurableEnvironment) {
            processPropertySource(propertySource);
        }
        else {
            logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
                    "]. Reason: Environment must implement ConfigurableEnvironment");
        }
    }

    //处理@ComponentScans,根据注解上面配置的组件扫描信息来做包扫描获取BeanDefinitions
    // Process any @ComponentScan annotations
    Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
            sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
    //这里判断是否满足注解上面的@Conditional相关的条件
    if (!componentScans.isEmpty() &&
            !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
        for (AnnotationAttributes componentScan : componentScans) {
            //在这里直接进行组件扫描,扫描完会直接注册到应用上下文中
            // The config class is annotated with @ComponentScan -> perform the scan immediately
            Set<BeanDefinitionHolder> scannedBeanDefinitions =
                    this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
            //这里对新增的这部分BeanDefinition做ConfigurationClass解析,如果不在这里做,
            //其他在上面的ConfigurationClassPostProcessor中也会做循环检查的时候也能够检查到并作处理
            // Check the set of scanned definitions for any further config classes and parse recursively if needed
            for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(
                        holder.getBeanDefinition(), this.metadataReaderFactory)) {
                    parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
                }
            }
        }
    }

    //处理@Import注解,getImports(sourceClass)方法是递归收集当前sourceClass上的@Import注解配置的值,
    //如果是其他注解会继续递归获取注解中注解的@Import,即收集所有能关联到的@Import注解中的value
    //该注解的值分为三类1.ImportSelector的实现类 2.ImportBeanDefinitionRegistrar的实现类 3.一般类(作为普通的需要处理配置注解的类来处理)。
    // Process any @Import annotations
    processImports(configClass, sourceClass, getImports(sourceClass), true);

    //处理@ImportResource注解
    // Process any @ImportResource annotations
    AnnotationAttributes importResource =
            AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
    if (importResource != null) {
        String[] resources = importResource.getStringArray("locations");
        Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
        for (String resource : resources) {
            String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
            configClass.addImportedResource(resolvedResource, readerClass);
        }
    }

    //这里是获取方法中的@Bean,类似xml形式,只不过是通过注解来提供BeanDefinition信息
    // Process individual @Bean methods
    Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
    for (MethodMetadata methodMetadata : beanMethods) {
        configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    }

    //这里实现的是获取接口中的default方法提供的@Bean注解BeanDefinition信息
    // Process default methods on interfaces
    processInterfaces(configClass, sourceClass);

    //获取superClass交给上面的循环处理父类中的配置注解
    // Process superclass, if any
    if (sourceClass.getMetadata().hasSuperClass()) {
        String superclass = sourceClass.getMetadata().getSuperClassName();
        if (superclass != null && !superclass.startsWith("java") &&
                !this.knownSuperclasses.containsKey(superclass)) {
            this.knownSuperclasses.put(superclass, configClass);
            // Superclass found, return its annotation metadata and recurse
            return sourceClass.getSuperClass();
        }
    }

    // No superclass -> processing is complete
    return null;
}
上面的方法主要是处理具体各个配置注解的实现。其中@Import实现了通过一般注解来导入@Import注解。

例如:
@GeneralAnnotation
class A {}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(XXX.class)
@intereface GeneralAnnotation{

}
这种是可以解析到GeneralAnnotation上面的@Import并进行处理的。

@PropertySources的处理细节
这个注解主要是对environment的一个补充配置,导入其他配置信息
下面的PropertySource注解中的属性
public @interface PropertySource {
    //配置资源的名称
    String name() default "";
    //资源地址,可以使用占位符
    String[] value();
    //如果资源未找到是否抛出异常
    boolean ignoreResourceNotFound() default false;
    //资源编码
    String encoding() default "";
    //用来创建PropertySource的工厂类,如果不指定则使用org.springframework.core.io.support.DefaultPropertySourceFactory
    Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
        //下面是处理@PropertySource注解的属性
        String name = propertySource.getString("name");
        if (!StringUtils.hasLength(name)) {
            name = null;
        }
        String encoding = propertySource.getString("encoding");
        if (!StringUtils.hasLength(encoding)) {
            encoding = null;
        }
        String[] locations = propertySource.getStringArray("value");
        Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
        boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");

        Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
        PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
                DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));

        for (String location : locations) {
            try {
                //根据location以及对象工厂获取对应的Property资源并添加到environment中去,如果已经存在对应的
                //Property资源则通过CompositePropertySource来组合拓展
                String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);

                //这个resourceLoader是通过ConfigurationClassPostProcessor类中的ResourceLoaderAware进行接口注入的,查看应用上下文启动的refresh()方法
                //可以知道通过ResourceLoaderAware注入的对象实际是应用上下文对象。
                Resource resource = this.resourceLoader.getResource(resolvedLocation);
                //将加载到的资源跟environment关联起来
                addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
            }
            catch (IllegalArgumentException | FileNotFoundException | UnknownHostException ex) {
                // Placeholders not resolvable or resource not found when trying to open it
                if (ignoreResourceNotFound) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
                    }
                }
                else {
                    throw ex;
                }
            }
        }
    }
@ComponentScans注解处理的细节
该注解的作用于spring XML的 <context:component-scan> 元素一样
组件扫描是通过扫描解析器ComponentScanAnnotationParser类实现的
下面是parse方法的代码
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
        //构造扫描器对象
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
                componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

        //获取注解中配置的nameGenerator并通过反射进行实例化
        Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
        boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
        scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
                BeanUtils.instantiateClass(generatorClass));
        //下面部分都是sanner的一些配置情况
        //域模型的代理模式设置,表示这个域模式如果是代理对象是用接口代理(JDK) 还是类代理(CGLIB)
        ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
        //非默认情况下使用new AnnotationScopeMetadataResolver(scopedProxyMode);
        if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
            scanner.setScopedProxyMode(scopedProxyMode);
        }
        else {
            //ScopedProxyMode.DEFAULT情况下使用配置的ScopeMetadataResolver
            Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
            scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
        }

        //设置要扫描的资源模式,默认是**/*.class
        scanner.setResourcePattern(componentScan.getString("resourcePattern"));

        //包含过滤器
        for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
            for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                scanner.addIncludeFilter(typeFilter);
            }
        }
        //不包含过滤器
        for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
            for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                scanner.addExcludeFilter(typeFilter);
            }
        }
        //该资源路径下的bean默认的懒加载值
        boolean lazyInit = componentScan.getBoolean("lazyInit");
        if (lazyInit) {
            scanner.getBeanDefinitionDefaults().setLazyInit(true);
        }
        //要扫面的包
        Set<String> basePackages = new LinkedHashSet<>();
        String[] basePackagesArray = componentScan.getStringArray("basePackages");
        for (String pkg : basePackagesArray) {
            String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
                    ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
            basePackages.addAll(Arrays.asList(tokenized));
        }
        for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
            basePackages.add(ClassUtils.getPackageName(clazz));
        }
        if (basePackages.isEmpty()) {
            basePackages.add(ClassUtils.getPackageName(declaringClass));
        }

        scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
            @Override
            protected boolean matchClassName(String className) {
                return declaringClass.equals(className);
            }
        });
        //开始扫描
        return scanner.doScan(StringUtils.toStringArray(basePackages));
    }
上面代码主要是根据@ComponentSan注解配置对扫描器对象进行配置
下面是组件扫描器对象的扫描细节doScan
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Assert.notEmpty(basePackages, "At least one base package must be specified");
        Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
        for (String basePackage : basePackages) {
            //根据包名以及其他配置信息进行资源扫描解析出对应的BeanDefinition
            Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
            for (BeanDefinition candidate : candidates) {
                //处理域相关的属性
                ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                candidate.setScope(scopeMetadata.getScopeName());
                String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                if (candidate instanceof AbstractBeanDefinition) {
                    postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
                }
                //处理基于注解的其他属性@Lazy、@Primary、@DependsOn、@Role、@Description。。。
                if (candidate instanceof AnnotatedBeanDefinition) {
                    AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
                }

                if (checkCandidate(beanName, candidate)) {
                    //处理代理属性、并注册到应用上下文中
                    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                    //从applyScopedProxyMode这里可以看到spring对象代理对象也是通过Beandefinition进行配置的。
                    //在创建代理BeanDefinitionHolder的同时也会将原始BeanDefinition进行注册一份,名称为scopedTarget.originalBeanName
                    definitionHolder =
                            AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                    beanDefinitions.add(definitionHolder);
                    registerBeanDefinition(definitionHolder, this.registry);
                }
            }
        }
        return beanDefinitions;
    }
上面代码主要是执行组件扫描,获取到对应包中的BeanDefinition

下面查看@Import的处理细节
@Import的作用类似于spring XML中的<import/>元素
不过这个处理的是:
1.通过指定ImportSelector的实现类导入资源
2.通过指定ImportBeanDefinitionRegistrar的实现类实现自定义的BeanDefinition注册
3.通过指定普通类、接口或者注解的class对象,由ConfigurationClassParser来解析上面的注解信息
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
            Collection<SourceClass> importCandidates, boolean checkForCircularImports) throws IOException {

    if (importCandidates.isEmpty()) {
        return;
    }
    /*
     * 这里实现检察循环导入
     * 判断的原理就是利用栈结构在递归处理过程中,对每一个要处理的configClass先进行压栈,这样如果
     * 后续解析的configClass已经在栈中存在,而且导入类为当前类,那么则表示为循环导入。
     * 下面是个简单的例子:
     *  @Import(X.class)
     *  class A{}
     *  @Import(A.class)
     *  class X{}
     *
     */
    if (checkForCircularImports && isChainedImportOnStack(configClass)) {
        this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
    }
    else {
        this.importStack.push(configClass);
        try {
            for (SourceClass candidate : importCandidates) {
                //如果导入的资源是一个ImportSelector的实现类,那么会进行实例化,并调用selectImports方法进行进一步的导入
                if (candidate.isAssignable(ImportSelector.class)) {
                    // Candidate class is an ImportSelector -> delegate to it to determine imports
                    Class<?> candidateClass = candidate.loadClass();
                    ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
                    ParserStrategyUtils.invokeAwareMethods(
                            selector, this.environment, this.resourceLoader, this.registry);
                    if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
                        //记录需要延迟导入的ImportSelector
                        this.deferredImportSelectors.add(
                                new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
                    }
                    else {
                        String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
                        Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
                        //这里递归调不检查循环导入,是因为导入类还是当前类,不可能会产生循环引用
                        processImports(configClass, currentSourceClass, importSourceClasses, false);
                    }
                }
                //这个是实现根据@Import的配置来注册什么BeanDefinition的接口
                //创建完实现类对象,配置到configClass中,在ConfigurationClassPostProcessor中会通过ConfigurationClassBeanDefinitionReader
                //实现进行registerBeanDefinitions方法的调用,进行注册Beandefinition。
                else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
                    // Candidate class is an ImportBeanDefinitionRegistrar ->
                    // delegate to it to register additional bean definitions
                    Class<?> candidateClass = candidate.loadClass();
                    ImportBeanDefinitionRegistrar registrar =
                            BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
                    ParserStrategyUtils.invokeAwareMethods(
                            registrar, this.environment, this.resourceLoader, this.registry);
                    configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
                }
                else {
                    //如果是一个一般类或者注解,作为普通的配置类递归处理,这种情况可能会产生循环导入,
                    //因此在这里记录下这个资源类的导入类,以备循环导入检查使用。
                    // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
                    // process it as an @Configuration class
                    this.importStack.registerImport(
                            currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
                    processConfigurationClass(candidate.asConfigClass(configClass));
                }
            }
        }
        catch (BeanDefinitionStoreException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanDefinitionStoreException(
                    "Failed to process import candidates for configuration class [" +
                    configClass.getMetadata().getClassName() + "]", ex);
        }
        finally {
            this.importStack.pop();
        }
    }
}
从上面的代码可以看到spring对注解的注解这种层次关系支持的非常好,这样就可以让我们可以很灵活的组合注解使用,比如需要导入许多资源,
可以自定义一个注解,将那些导入注解打到自己的自定义注解上面。

下面查看@ImportResource的处理细节
该注解的作用于@Import、<import/> 类似  用来导入XML或者.groovy形式BeanDefinition文件的
 默认使用GroovyBeanDefinitionReader 处理.groovy文件
 默认使用XmlBeanDefinitionReader 是处理.xml文件
 对应locations配置同样也支持占位符
// Process any @ImportResource annotations
AnnotationAttributes importResource =
        AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
    String[] resources = importResource.getStringArray("locations");
    Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
    for (String resource : resources) {
        //占位符替换成实际值
        String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
        //待后面通过ConfigurationClassPostProcessor使用ConfigurationClassBeanDefinitionReader来loadBeanDefinition来加载通过该注解导入的资源xml或者.groovy
        configClass.addImportedResource(resolvedResource, readerClass);
    }
}
下面是@Bean注解方法标记处理细节
@Bean 跟spring XML中的<bean/> 元素是一样的作用
从上面的doProcessConfigurationClass方法中可以看到spring能够处理到当前类 + 接口中默认方法 + 父类中的 @Bean注解
2.1.2.关于AutowiredAnnotationBeanPostProcessor的实现细节
查看该类的继承以及接口信息
    1.MergedBeanDefinitionPostProcessor是BeanPostProcessor的子接口,拓展了Bean创建前处理BeanDefinition的回调
    2.InstantiationAwareBeanPostProcessorAdapter是一个SmartInstantiationAwareBeanPostProcessor的适配器,
        SmartInstantiationAwareBeanPostProcessor的父类是InstantiationAwareBeanPostProcessor的父类是BeanPostProcessor
        主要是拓展了Bean实例化时的一些回调。
    3.PriorityOrdered
    4.BeanFactoryAware
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
        implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
    ...
}
下面查看MergedBeanDefinitionPostProcessor中postProcessMergedBeanDefinition方法的实现
这个方法主要是将BeanDefinition中的依赖注入相关的注解信息解析出来,以备在实例化时进行依赖注入。
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    //处理依赖注入的元数据信息
    InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
    //检查元数据需不需要创建或者更新
    // Fall back to class name as cache key, for backwards compatibility with custom callers.
    String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
    // Quick check on the concurrent map first, with minimal locking.
    InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
        synchronized (this.injectionMetadataCache) {
            metadata = this.injectionMetadataCache.get(cacheKey);
            if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                if (metadata != null) {
                    metadata.clear(pvs);
                }
                //根据class去构造依赖注入的元数据
                metadata = buildAutowiringMetadata(clazz);
                this.injectionMetadataCache.put(cacheKey, metadata);
            }
        }
    }
    return metadata;
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
    LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
    Class<?> targetClass = clazz;

    do {
        final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
        //获取fields上面关于依赖注入的注解信息
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            //@Autowired 、@Value 、以及JSR-330中的@Inject
            AnnotationAttributes ann = findAutowiredAnnotation(field);
            if (ann != null) {
                if (Modifier.isStatic(field.getModifiers())) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Autowired annotation is not supported on static fields: " + field);
                    }
                    return;
                }
                //是否必须属性(默认是必须存在)
                boolean required = determineRequiredStatus(ann);
                currElements.add(new AutowiredFieldElement(field, required));
            }
        });
        //方法上面的依赖注入相关注解处理
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                if (Modifier.isStatic(method.getModifiers())) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Autowired annotation is not supported on static methods: " + method);
                    }
                    return;
                }
                if (method.getParameterCount() == 0) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Autowired annotation should only be used on methods with parameters: " +
                                method);
                    }
                }
                boolean required = determineRequiredStatus(ann);
                //这里如果方法是read、write方法的话也将对应的javaBean内省信息放到元属性中
                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                currElements.add(new AutowiredMethodElement(method, required, pd));
            }
        });

        elements.addAll(0, currElements);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return new InjectionMetadata(clazz, elements);
}
下面是解析有效构造方法的回调实现,这个回调是在构造Bean实例时用来确定构造器的
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
        throws BeanCreationException {
        ...
}
下面是实现依赖注入的方法
通过本处理器处理的是@Autowired注解因此这里面是使用AutowiredFieldElement.inject实现的具体的注入逻辑
@Override
public PropertyValues postProcessPropertyValues(
        PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
    //获取实例的依赖注入的元数据信息
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    try {
        //执行依赖注入的逻辑
        metadata.inject(bean, beanName, pvs);
    }
    catch (BeanCreationException ex) {
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
    }
    return pvs;
}
下面是InjectionMetadata中的inject方法。这里是遍历需要执行依赖注入的元素然后通过元素进行注入
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        Collection<InjectedElement> checkedElements = this.checkedElements;
        Collection<InjectedElement> elementsToIterate =
                (checkedElements != null ? checkedElements : this.injectedElements);
        if (!elementsToIterate.isEmpty()) {
            boolean debug = logger.isDebugEnabled();
            for (InjectedElement element : elementsToIterate) {
                if (debug) {
                    logger.debug("Processing injected element of bean '" + beanName + "': " + element);
                }
                element.inject(target, beanName, pvs);
            }
        }
    }
下面是AutowiredFieldElement中inject方法
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Field field = (Field) this.member;
    Object value;
    if (this.cached) {
        value = resolvedCachedArgument(beanName, this.cachedFieldValue);
    }
    else {
        //构造出DependencyDescriptor交给对象工厂来确定要注入的对象
        DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
        desc.setContainingClass(bean.getClass());
        Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
        Assert.state(beanFactory != null, "No BeanFactory available");
        TypeConverter typeConverter = beanFactory.getTypeConverter();
        try {
            value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
        }
        catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
        }
        //处理字段注入的缓存
        synchronized (this) {
            if (!this.cached) {
                if (value != null || this.required) {
                    this.cachedFieldValue = desc;
                    registerDependentBeans(beanName, autowiredBeanNames);
                    if (autowiredBeanNames.size() == 1) {
                        String autowiredBeanName = autowiredBeanNames.iterator().next();
                        if (beanFactory.containsBean(autowiredBeanName)) {
                            if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                                this.cachedFieldValue = new ShortcutDependencyDescriptor(
                                        desc, autowiredBeanName, field.getType());
                            }
                        }
                    }
                }
                else {
                    this.cachedFieldValue = null;
                }
                this.cached = true;
            }
        }
    }
    if (value != null) {
        ReflectionUtils.makeAccessible(field);
        field.set(bean, value);
    }
}
通过方法注入与fields注入类似
2.1.2.关于RequiredAnnotationBeanPostProcessor的实现细节
这个实现的内容比较简单,在Bean实例化完毕,参数设置完毕之后。
主要是检查如果如果setter上有注解@Required而实例内的对应字段没有值的话,会抛出BeanInitializationException
@Override
public PropertyValues postProcessPropertyValues(
        PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

    if (!this.validatedBeanNames.contains(beanName)) {
        if (!shouldSkip(this.beanFactory, beanName)) {
            List<String> invalidProperties = new ArrayList<>();
            for (PropertyDescriptor pd : pds) {
                if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
                    invalidProperties.add(pd.getName());
                }
            }
            if (!invalidProperties.isEmpty()) {
                throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
            }
        }
        this.validatedBeanNames.add(beanName);
    }
    return pvs;
}
2.1.2.关于CommonAnnotationBeanPostProcessor的实现细节
该处理器与AutowiredAnnotationBeanPostProcessor类似,只不过是处理关于@Resource、@WebServiceRef、@EJB
注解的依赖注入
实现具体注入逻辑的类分别是ResourceElement、WebServiceRefElement、EjbRefElement
2.1.2.关于EventListenerMethodProcessor的实现细节
该处理器实现了SmartInitializingSingleton接口,
void afterSingletonsInstantiated();
方法是在单例对象实例化之后进行回调的。
@Override
public void afterSingletonsInstantiated() {
    List<EventListenerFactory> factories = getEventListenerFactories();
    ConfigurableApplicationContext context = getApplicationContext();
    String[] beanNames = context.getBeanNamesForType(Object.class);
    for (String beanName : beanNames) {
        //如果是对象的scope设置为代理方式,会创建一个target对象,这个对象是scopedTarget.xxx的beanName命名
        if (!ScopedProxyUtils.isScopedTarget(beanName)) {
            Class<?> type = null;
            //下面的代码都是获取到目标对象的class对象的处理
            try {
                type = AutoProxyUtils.determineTargetClass(context.getBeanFactory(), beanName);
            }
            catch (Throwable ex) {
                // An unresolvable bean type, probably from a lazy bean - let's ignore it.
                if (logger.isDebugEnabled()) {
                    logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
                }
            }
            if (type != null) {
                if (ScopedObject.class.isAssignableFrom(type)) {
                    try {
                        Class<?> targetClass = AutoProxyUtils.determineTargetClass(
                                context.getBeanFactory(), ScopedProxyUtils.getTargetBeanName(beanName));
                        if (targetClass != null) {
                            type = targetClass;
                        }
                    }
                    catch (Throwable ex) {
                        // An invalid scoped proxy arrangement - let's ignore it.
                        if (logger.isDebugEnabled()) {
                            logger.debug("Could not resolve target bean for scoped proxy '" + beanName + "'", ex);
                        }
                    }
                }
                try {
                    //这里才是真正处理@EventListener的逻辑
                    processBean(factories, beanName, type);
                }
                catch (Throwable ex) {
                    throw new BeanInitializationException("Failed to process @EventListener " +
                            "annotation on bean with name '" + beanName + "'", ex);
                }
            }
        }
    }
}
下面查看processBean(factories, beanName, type);方法
protected void processBean(
            final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {

    if (!this.nonAnnotatedClasses.contains(targetType)) {
        Map<Method, EventListener> annotatedMethods = null;
        try {
            //获取类中带有@EventListener注解标记的方法
            //通过查看MethodIntrospector.selectMethods方法可以得知,所有接口中的方法带有@EventListener注解也是有效的。
            annotatedMethods = MethodIntrospector.selectMethods(targetType,
                    (MethodIntrospector.MetadataLookup<EventListener>) method ->
                            AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
        }
        catch (Throwable ex) {
            // An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
            if (logger.isDebugEnabled()) {
                logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
            }
        }
        if (CollectionUtils.isEmpty(annotatedMethods)) {
            this.nonAnnotatedClasses.add(targetType);
            if (logger.isTraceEnabled()) {
                logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
            }
        }
        else {
            // Non-empty set of methods
            ConfigurableApplicationContext context = getApplicationContext();
            for (Method method : annotatedMethods.keySet()) {
                //这里的EventListenerFactory是通过应用上下文中根据类型或取的,因此,只要定义了这种类型的接口实现交给spring容器管理,就能参与处理
                for (EventListenerFactory factory : factories) {
                    if (factory.supportsMethod(method)) {
                        Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
                        //通过EventListenerFactory构造出ApplicationListener,如果是通过DefaultEventListenerFactory创建的话
                        //是利用ApplicationListenerMethodAdapter来实现的ApplicationListener接口与注解标记方法的适配。
                        ApplicationListener<?> applicationListener =
                                factory.createApplicationListener(beanName, targetType, methodToUse);
                        if (applicationListener instanceof ApplicationListenerMethodAdapter) {
                            //ApplicationListenerMethodAdapter实现了@Conditional条件相关的注解,EventExpressionEvaluator是条件相关注解的解析实现。
                            //这里需要对这个进行初始化设置一下,而context是用来发布ApplicationListener事件的
                            //在这个方法的实现中会对方法的返回值再次作为容器事件进行发布
                            ((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
                        }
                        context.addApplicationListener(applicationListener);
                        break;
                    }
                }
            }
            if (logger.isDebugEnabled()) {
                logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
                        beanName + "': " + annotatedMethods);
            }
        }
    }
}
利用@EvenListenter相较基于接口实现类的方式可以更简洁的实现基于容器的消息总线。
另外还可以结合@Asyn注解来实现异步处理事件。
2.1.2.关于DefaultEventListenerFactory
该处理器是spring提供的默认@EventListener的容器监听器的对象工厂。用来创建ApplicationListenerMethodAdapter的

猜你喜欢

转载自blog.csdn.net/m0_38043362/article/details/80284501
今日推荐