Spring源碼6:createApplicationContext()實例AnnotationConfigServletWebServerApplicationContext

上篇回顧

上一篇printBanner()打印Banner中非了springboot如何打印Banner


目錄

1. 創(chuàng)建應(yīng)用上下文
2. DefaultResourceLoader
3. AbstractApplicationContext
4. GenericApplicationContext
????4.1 SimpleAliasRegistry
????4.2 DefaultSingletonBeanRegistry
????4.3 FactoryBeanRegistrySupport
????4.4 AbstractBeanFactory
????4.5 AbstractAutowireCapableBeanFactory
????4.6 DefaultListableBeanFactory
????4.1 SimpleAliasRegistry
5. GenericWebApplicationContext
6. ServletWebServerApplicationContext
7.AnnotationConfigServletWebServerApplicationContext
????7.1 AnnotatedBeanDefinitionReader
????7.2 ClassPathBeanDefinitionScanner
8. 總結(jié)

1. 創(chuàng)建應(yīng)用上下文

初始化SpringApplication實例中, 已經(jīng)分析了當前模塊web類型為SERVLET, 所以當前實例化了一個AnnotationConfigServletWebServerApplicationContext對象

public class SpringApplication {
    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        //應(yīng)用上下文
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            configureIgnoreBeanInfo(environment);
            Banner printedBanner = printBanner(environment);
            //本文的重點
            //創(chuàng)建應(yīng)用上下文
            //AnnotationConfigServletWebServerApplicationContext
            context = createApplicationContext();
        //...
    }
    
    public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
            + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";

    //創(chuàng)建應(yīng)用上下文
    protected ConfigurableApplicationContext createApplicationContext() {
    Class<?> contextClass = this.applicationContextClass;
    if (contextClass == null) {
        try {
            switch (this.webApplicationType) {
            case SERVLET:
                //我們使用的是servlet web環(huán)境
                //實例化AnnotationConfigServletWebServerApplicationContext對象
                contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
                break;
            case REACTIVE:
                contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                break;
            default:
                contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
            }
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                    "Unable create a default ApplicationContext, "
                            + "please specify an ApplicationContextClass",
                    ex);
        }
    }
    //返回的是一個AnnotationConfigServletWebServerApplicationContext對象
    return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
}

由上面類圖,我們可以看出, 類繼承關(guān)系如下:

  • AnnotationConfigServletWebServerApplicationContext類繼承了ServletWebServerApplicationContext
  • ServletWebServerApplicationContext繼承了GenericWebApplicationContext
  • GenericWebApplicationContext繼承了GenericApplicationContext
  • GenericApplicationContext繼承了AbstractApplicationContext
  • AbstractApplicationContext繼承了DefaultResourceLoader

2. DefaultResourceLoader

用來加載Resource, 初始化的過程中, 實例化了ClassLoader,

//默認的資源加載器
public class DefaultResourceLoader implements ResourceLoader {
   @Nullable
    private ClassLoader classLoader;

    //自定義ProtocolResolver, 用于獲取資源
    private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);

    //
    private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);
    
    //實例化ClassLoader
    public DefaultResourceLoader() {
        this.classLoader = ClassUtils.getDefaultClassLoader();
    }
    
    //加載資源
    @Override
    public Resource getResource(String location) {
        Assert.notNull(location, "Location must not be null");

        //自定義資源加載方式
        for (ProtocolResolver protocolResolver : this.protocolResolvers) {
            //調(diào)用ProtocolResolver的resolve方法
            Resource resource = protocolResolver.resolve(location, this);
            if (resource != null) {
                //如果獲取到資源,立即返回
                return resource;
            }
        }
        
        if (location.startsWith("/")) {
            //先判斷是否是根目錄
            return getResourceByPath(location);
        }
        else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
            //再判斷是否是classpath下的資源
            return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
        }
        else {
            try {
                //先當做一個URL處理
                URL url = new URL(location);
                //先判斷是否是一個file
                //不是file的話,再從URL中獲取
                return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));
            }
            catch (MalformedURLException ex) {
                //獲取不到資源的話
                //當做resource處理
                return getResourceByPath(location);
            }
        }
    }
}

3. AbstractApplicationContext

抽象ApplicationContext, 定義了ApplicationContext一些模板方法, 在實例化的過程中, 調(diào)用了getResourcePatternResolver()方法, 構(gòu)造了一個PathMatchingResourcePatternResolver, 規(guī)定了如何查找資源, 例如從classpath, 根路徑, 從war包等查找資源

public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    
    private ResourcePatternResolver resourcePatternResolver;
    //初始化一個resourcePatternResolver
    public AbstractApplicationContext() {
        this.resourcePatternResolver = getResourcePatternResolver();
    }
    
    //該方法被GenericWebApplicationContext類重寫
    //實際調(diào)用的是GenericWebApplicationContext的getResourcePatternResolver()方法
    protected ResourcePatternResolver getResourcePatternResolver() {
        //this實現(xiàn)了DefaultResourceLoader
        //可以作為PathMatchingResourcePatternResolver構(gòu)造函數(shù)的參數(shù)
        return new PathMatchingResourcePatternResolver(this);
    }
}

4. GenericApplicationContext

初始化了一個DefaultListableBeanFactory

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
    private final DefaultListableBeanFactory beanFactory;
    //初始化beanFactory
    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
}

由上面類圖, 我們可以看出DefaultListableBeanFactory的繼承關(guān)系:

  • DefaultListableBeanFactory繼承了AbstractAutowireCapableBeanFactory
  • AbstractAutowireCapableBeanFactory繼承了AbstractBeanFactory
  • AbstractBeanFactory繼承了FactoryBeanRegistrySupport
  • FactoryBeanRegistrySupport繼承了DefaultSingletonBeanRegistry
  • DefaultSingletonBeanRegistry繼承了SimpleAliasRegistry
4.1 SimpleAliasRegistry

提供了bean別名的增刪改查功能

public class SimpleAliasRegistry implements AliasRegistry {

    //key是bean別名
    //value是原始bean名稱
    private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
}
4.2 DefaultSingletonBeanRegistry

默認的單例Bean注冊器, 提供了單例bean增刪改查等功能

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    //緩存單例bean, key為bean名稱,value為bean實例
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    //緩存beanFactory, key為bean名稱,value為beanFactory
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    //早期單例緩存, key為bean名稱,value為bean實例
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    //單例bean名稱set
    private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

    //正在創(chuàng)建的單例bean名稱set
    private final Set<String> singletonsCurrentlyInCreation =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    //當前在創(chuàng)建檢查中排除的bean名稱set
    private final Set<String> inCreationCheckExclusions =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    //異常set
    @Nullable
    private Set<Exception> suppressedExceptions;

    //正在銷毀的bean名稱set
    private boolean singletonsCurrentlyInDestruction = false;

    //一次性的bean實例
    private final Map<String, Object> disposableBeans = new LinkedHashMap<>();

    //bean包含關(guān)系map, key為bean名稱, value為被包含的bean名稱
    private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);

    //bean依賴關(guān)系緩存, key為bean名稱,value為依賴該bean的bean名稱
    private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

    //bean依賴關(guān)系緩存,key為bean名稱,value為該bean依賴的bean名稱
    private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
}
4.3 FactoryBeanRegistrySupport

提供了FactoryBean的增刪改查方法

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

    //緩存FactoryBean單例的Map
    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
}
4.4 AbstractBeanFactory

抽象BeanFactory, 定義了通用的beanFactory的模板方法, 添加了對beanFactory對Scope的支持, scope主要有五種, singleton, prototype, request, session和application,

  • ConfigurableBeanFactory定義兩個SCOPE
    • SCOPE_SINGLETON = "singleton"
    • SCOPE_PROTOTYPE = "prototype"
  • WebApplicationContext接口中定義了三個SCOPE
    • SCOPE_REQUEST = "request"
    • SCOPE_SESSION = "session"
    • SCOPE_APPLICATION = "application"
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    //自定義PropertyEditorRegistrar屬性編輯器注冊器
    //用于編輯Factory下的所有bean
    private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
    
    //自定義PropertyEditor屬性編輯器
    private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4);

    //String值解析器
    private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>();

    //Bean創(chuàng)建處理器
    private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
    
    //Bean Scope范圍支持
    //父接口ConfigurableBeanFactory中定義了兩個SCOPE
    //SCOPE_SINGLETON = "singleton";
    //SCOPE_PROTOTYPE = "prototype";
    //WebApplicationContext接口中定義了三個SCOPE
    //SCOPE_REQUEST = "request";
    //SCOPE_SESSION = "session";
    //SCOPE_APPLICATION = "application"
    private final Map<String, Scope> scopes = new LinkedHashMap<>(8);

}
4.5 AbstractAutowireCapableBeanFactory

抽象自動配置BeanFactory, 實現(xiàn)了創(chuàng)建Bean, 實例化Bean, 字段配置Bean, 自動裝配依賴Bean的方法

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    //創(chuàng)建Bean策略,默認為cglib
    private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

    public AbstractAutowireCapableBeanFactory() {
        //顯示調(diào)用父類方法
        super();
        
        //自動裝配忽略BeanNameAware接口
        ignoreDependencyInterface(BeanNameAware.class);
        //自動裝配忽略BeanFactoryAware接口
        ignoreDependencyInterface(BeanFactoryAware.class);
        //自動裝配忽略BeanClassLoaderAware接口
        ignoreDependencyInterface(BeanClassLoaderAware.class);
    }
}
4.6 DefaultListableBeanFactory

BeanFactory默認實現(xiàn), spring IOC默認容器類

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
        
    //key為依賴類型, value為自動配置的值
    private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

    //key為bean名稱, value為bean定義
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

    //key為依賴的類型, value為所有bean名稱列表
    private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

    //key為依賴類型, value為單例bean的名稱數(shù)組
    private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

    //按注冊的順序, 記錄的bean名稱列表
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

    //手動添加的bean名稱列表
    private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);


    public DefaultListableBeanFactory() {
        //顯示調(diào)用父類構(gòu)造函數(shù)
        super();
    }
}

5. GenericWebApplicationContext

重寫了AbstractApplicationContext的getResourcePatternResolver()方法, 返回一個ServletContextResourcePatternResolver對象, 構(gòu)造函數(shù)中顯示調(diào)用父類GenericApplicationContext的構(gòu)造函數(shù)

public class GenericWebApplicationContext extends GenericApplicationContext
        implements ConfigurableWebApplicationContext, ThemeSource {
    //顯式調(diào)用父GenericApplicationContext類構(gòu)造方法
    //什么都不做
    public GenericWebApplicationContext() {
        super();
    }
    
    //ServletContextResourcePatternResolver
    //重寫了父類獲取資源的邏輯
    //從ServletContext中獲取資源
    @Override
    protected ResourcePatternResolver getResourcePatternResolver() {
        return new ServletContextResourcePatternResolver(this);
    }
}

6. ServletWebServerApplicationContext

隱式調(diào)用父類GenericWebApplicationContext構(gòu)造函數(shù), 什么都沒有做

public class ServletWebServerApplicationContext extends GenericWebApplicationContext
        implements ConfigurableWebServerApplicationContext {
    //什么都不做
    //隱式調(diào)用父類GenericWebApplicationContext構(gòu)造方法
    public ServletWebServerApplicationContext() {
    }
}

7.AnnotationConfigServletWebServerApplicationContext

首先, 初始化一個AnnotatedBeanDefinitionReader, 然后再實例化一個ClassPathBeanDefinitionScanner對象

//注解配置ServletWeb服務(wù)應(yīng)用上下文
//當前SpringApplication上下文
public class AnnotationConfigServletWebServerApplicationContext
        extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {

    //注解Bean讀取器,用來去取bean
    private final AnnotatedBeanDefinitionReader reader;

    //ClassPath中的Bean掃描器,用來掃描bean
    private final ClassPathBeanDefinitionScanner scanner;

    //被注冊到容器中的Class對象列表
    private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();

    //需要掃描的包
    private String[] basePackages;

    //構(gòu)造函數(shù)
    public AnnotationConfigServletWebServerApplicationContext() {
        //注解Bean讀取器 傳入this
        this.reader = new AnnotatedBeanDefinitionReader(this);
        //Classpath中的Bean掃描器
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
}
7.1 AnnotatedBeanDefinitionReader();

用于讀取和解析bean定義

//注解Bean讀取器
//用來讀取和解析bean
public class AnnotatedBeanDefinitionReader {

    private final BeanDefinitionRegistry registry;

    //bean名稱生成器
    private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();

    //Scope解析器
    private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

    private ConditionEvaluator conditionEvaluator;
    
    //registry傳入的AnnotationConfigServletWebServerApplicationContext對象
    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, getOrCreateEnvironment(registry));
    }

    //構(gòu)造函數(shù)
    //傳入的registry就是AnnotationConfigServletWebServerApplicationContext實例
    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;
        //條件評估器的初始化
        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
        //注解配置注冊器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }
    
    //獲取或創(chuàng)建環(huán)境
    private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        if (registry instanceof EnvironmentCapable) {
            //實現(xiàn)了EnvironmentCapable
            //調(diào)用了AbstractApplicationContext中的getEnvironment方法
            //獲取到了StandardEnvironment實例
            return ((EnvironmentCapable) registry).getEnvironment();
        }
        return new StandardEnvironment();
    }
}
AnnotationBeanNameGenerator

注解bean名稱生成器, 用于生成Bean名稱

//bean名稱生成器
//主要為Component注解生成名稱
//包括Component子注解: Component已添,Respository妥箕,Service,Controller
//還包括java6的ManagedBean
public class AnnotationBeanNameGenerator implements BeanNameGenerator {
    //Spring Component注解
    private static final String COMPONENT_ANNOTATION_CLASSNAME = "org.springframework.stereotype.Component";

    @Override
    public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
        //如果是注解的bean定義
        if (definition instanceof AnnotatedBeanDefinition) {
            //先從注解獲取bean名稱
            String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
            //不為空直接返回
            if (StringUtils.hasText(beanName)) {
                return beanName;
            }
        }
        //注解沒有定義bean名稱,那么構(gòu)造一個bean名稱
        return buildDefaultBeanName(definition, registry);
    }


    /**
     * 構(gòu)造bean名稱
     */
    protected String buildDefaultBeanName(BeanDefinition definition) {
        String beanClassName = definition.getBeanClassName();
        Assert.state(beanClassName != null, "No bean class name set");
        //獲取Class名稱
        String shortClassName = ClassUtils.getShortName(beanClassName);
        //將類名作為bean名稱
        return Introspector.decapitalize(shortClassName);
    }
}

public class Introspector {
    public static String decapitalize(String name) {
        if (name == null || name.length() == 0) {
            return name;
        }
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                        Character.isUpperCase(name.charAt(0))){
            //如果第一個和第二個字符都是大寫,直接返回名稱
            return name;
        }
        //將第一個字符轉(zhuǎn)換為小寫,返回類名
        char chars[] = name.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }
}

AnnotationScopeMetadataResolver

Scope注解的解析器, 解析出Scope的模式ScopedProxyMode, 以及Scope的名稱

//@Scope注解的解析器
public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {
    
    //Scope注解
    protected Class<? extends Annotation> scopeAnnotationType = Scope.class;
      
    //代理模式
    private final ScopedProxyMode defaultProxyMode;
    
    //默認不使用代理
    public AnnotationScopeMetadataResolver() {
        this.defaultProxyMode = ScopedProxyMode.NO;
    }
    
    //解析@Scope注解
    public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
        ScopeMetadata metadata = new ScopeMetadata();
        if (definition instanceof AnnotatedBeanDefinition) {
            //注解bean
            AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition)definition;
            
            //獲取到metadata放入名為attributes的map中
            AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(annDef.getMetadata(), this.scopeAnnotationType);
            if (attributes != null) {
                //將@Scope注解的value和proxyMode放入到metadata中
                metadata.setScopeName(attributes.getString("value"));
                ScopedProxyMode proxyMode = (ScopedProxyMode)attributes.getEnum("proxyMode");
                if (proxyMode == ScopedProxyMode.DEFAULT) {
                    proxyMode = this.defaultProxyMode;
                }
                metadata.setScopedProxyMode(proxyMode);
            }
        }
        return metadata;
    }
}

//代理模式枚舉
public enum ScopedProxyMode {

    //默認代理模式,默認使NO,
    //如果在component-scan中配置了默認值,將會使用這個默認值
    DEFAULT,

    //不使用代理
    NO,

    //接口,使用jdk動態(tài)代理
    INTERFACES,

    //類,使用cglib動態(tài)代理
    TARGET_CLASS;
}
ConditionEvaluator

@Conditional注解的條件評估器, 評估是否滿足條件

//@Conditional注解的解析器
//也可用于@ConditionalOnBean,@ConditionalOnClass,@ConditionalOnExpression,@ConditionalOnMissingBean等子注解
class ConditionEvaluator {

    //內(nèi)部類
    private final ConditionContextImpl context;
    //構(gòu)造函數(shù)
    public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,
            @Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
        this.context = new ConditionContextImpl(registry, environment, resourceLoader);
    }
    
    //判斷是否應(yīng)該跳過
    public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
        if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
            //metadata為空或者沒有使用@Conditional注解,不跳過
            return false;
        }

        if (phase == null) {
            //ConfigurationPhase對象為空,也就是沒有設(shè)置生效條件
            if (metadata instanceof AnnotationMetadata &&
                    ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
                //如果是注解的話,使用PARSE_CONFIGURATION配置驗證是否跳過
                return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
            }
            //不是注解的話,使用REGISTER_BEAN配置驗證是否跳過
            return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
        }

        List<Condition> conditions = new ArrayList<>();
        //遍歷配置類的條件注解,得到條件數(shù)據(jù),放到conditions集合中
        for (String[] conditionClasses : getConditionClasses(metadata)) {
            for (String conditionClass : conditionClasses) {
                Condition condition = getCondition(conditionClass, this.context.getClassLoader());
                conditions.add(condition);
            }
        }

        //按Order注解排序
        AnnotationAwareOrderComparator.sort(conditions);
        //條件排序
        for (Condition condition : conditions) {
            ConfigurationPhase requiredPhase = null;
            if (condition instanceof ConfigurationCondition) {
                requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
            }
            //添加驗證滿足,那就跳過
            if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
                return true;
            }
        }

        return false;
    }
    
    //私有靜態(tài)內(nèi)部類
    private static class ConditionContextImpl implements ConditionContext {
    
        public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,
                @Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
            //傳入的是AnnotationConfigServletWebServerApplicationContext對象
            this.registry = registry;
            this.beanFactory = deduceBeanFactory(registry);
            this.environment = (environment != null ? environment : deduceEnvironment(registry));
            this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
            this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
        }

        //推斷獲取beanFactory
        @Nullable
        private ConfigurableListableBeanFactory deduceBeanFactory(@Nullable BeanDefinitionRegistry source) {
            if (source instanceof ConfigurableListableBeanFactory) {
                return (ConfigurableListableBeanFactory) source;
            }
            if (source instanceof ConfigurableApplicationContext) {
                //AnnotationConfigServletWebServerApplicationContext實現(xiàn)了ConfigurableApplicationContext
                //調(diào)用了GenericApplicationContext中的getBeanFactory方法
                //獲取到一個DefaultListableBeanFactory對象
                return (((ConfigurableApplicationContext) source).getBeanFactory());
            }
            return null;
        }

        //獲取環(huán)境
        private Environment deduceEnvironment(@Nullable BeanDefinitionRegistry source) {
            if (source instanceof EnvironmentCapable) {
                //AnnotationConfigServletWebServerApplicationContex實現(xiàn)了EnvironmentCapable
                //調(diào)用了AbstractApplicationContext中的getEnvironment方法
                //獲取到了StandardEnvironment實例
                return ((EnvironmentCapable) source).getEnvironment();
            }
            return new StandardEnvironment();
        }

        //獲取ResourceLoader
        private ResourceLoader deduceResourceLoader(@Nullable BeanDefinitionRegistry source) {
            if (source instanceof ResourceLoader) {
                //AnnotationConfigServletWebServerApplicationContex實現(xiàn)了ResourceLoader
                //所以直接強轉(zhuǎn)
                return (ResourceLoader) source;
            }
            return new DefaultResourceLoader();
        }

        //獲取ClassLoader
        @Nullable
        private ClassLoader deduceClassLoader(@Nullable ResourceLoader resourceLoader,
                @Nullable ConfigurableListableBeanFactory beanFactory) {
            //傳入ResourceLoader為null
            if (resourceLoader != null) {
                ClassLoader classLoader = resourceLoader.getClassLoader();
                if (classLoader != null) {
                    return classLoader;
                }
            }
            if (beanFactory != null) {
                //獲取到beanFactory不為null
                //使用beanFactory中的classloader
                return beanFactory.getBeanClassLoader();
            }
            return ClassUtils.getDefaultClassLoader();
        }

}
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)

注冊bean處理器, bean名稱需要加上org.springframework.context.annotation前綴:

  1. beanFactory設(shè)置AnnotationAwareOrderComparator
    • 處理Ordered類酝碳、@Order注解和@Priority
    • 處理完成之后排序
  2. beanFactory設(shè)置ContextAnnotationAutowireCandidateResolver
    • 處理@Lazy注解
    • 配置延遲加載
  3. 注冊ConfigurationClassPostProcessor類型的bean
    • 處理@Configuration注解
    • 非常重要的一個類
    • bean名稱為internalConfigurationAnnotationProcessor
  4. 注冊AutowiredAnnotationBeanPostProcessor類型的bean
    • 處理@Autowired, @Value注解
    • bean名稱為internalAutowiredAnnotationProcessor
  5. 注冊CommonAnnotationBeanPostProcessor類型的bean
    • 處理@PostConstruct,@PreDestroy注解
    • bean名稱為internalCommonAnnotationProcessor
  6. 注冊EventListenerMethodProcessor類型的bean
    • 處理@EventListener注解
    • bean名稱為internalEventListenerProcessor
  7. 注冊DefaultEventListenerFactory類型的bean
    • 默認的監(jiān)聽器工廠
    • 處理@EventListener注解
    • bean名稱為internalEventListenerFactory
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
        BeanDefinitionRegistry registry, @Nullable Object source) {

    //獲取到父類GenericApplicationContext的beanFactory
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
        //添加注解排序器
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            //AnnotationAwareOrderComparator處理Ordered類矾踱、@Order注解和@Priority
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
        //處理@Lazy注解
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }

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

    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        //注冊ConfigurationClassPostProcessor類型的bean 
        //處理@Configuration注解
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        //注冊類型AutowiredAnnotationBeanPostProcessor的bean
        //處理@Autowired,@Value注解
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        //注冊類型CommonAnnotationBeanPostProcessor的bean
        //處理@PostConstruct和@PreDestroy注解
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        //注冊一個名稱為PersistenceAnnotationBeanPostProcessor,類型為PersistenceAnnotationBeanPostProcessor的bean
        //處理@PersistenceUnit,@PersistenceContext注解
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            //我們沒有用到PersistenceAnnotationBeanPostProcessor
            //所以不會添加
            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));
    }

    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
        //注冊類型為EventListenerMethodProcessor的bean
        //處理@EventListener注解
        RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }

    if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
        //注冊類型為DefaultEventListenerFactory的bean
        //EventListenerFactory的默認實現(xiàn),支持EventListener注解
        RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
    }

    return beanDefs;
}
7.2 ClassPathBeanDefinitionScanner

如果basePackages不為空的話, 掃描basePackages中定義的bean, 當前應(yīng)用中沒有配置basePackages, 所以ClassPathBeanDefinitionScanner不會去掃描bean

//ClassPath中Bean掃描器
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
    
    private final BeanDefinitionRegistry registry;

    private BeanDefinitionDefaults beanDefinitionDefaults = new BeanDefinitionDefaults();

    @Nullable
    private String[] autowireCandidatePatterns;

    private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();

    private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

    private boolean includeAnnotationConfig = true;

    // registry是AnnotationConfigServletWebServerApplicationContext的實例
    //useDefaultFilters默認為true
    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
            Environment environment, @Nullable ResourceLoader resourceLoader) {

        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        this.registry = registry;

        if (useDefaultFilters) {
            //添加@Component,@ManagedBean,@Named注解掃描
            registerDefaultFilters();
        }
        
        //getOrCreateEnvironment(registry)
        //得到一個StandardEnvironment
        setEnvironment(environment);
        
        // (registry instanceof ResourceLoader ? (ResourceLoader) registry : null
        //registry實現(xiàn)了ResourceLoader,registry強轉(zhuǎn)為ResourceLoader
        setResourceLoader(resourceLoader);
    }
    
    @SuppressWarnings("unchecked")
    protected void registerDefaultFilters() {
        //添加一個Component注解掃描
        //Compent注解包括子注解:Repository,Service,Controller
        this.includeFilters.add(new AnnotationTypeFilter(Component.class));
        ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
        try {
            //添加ManagedBean注解
            this.includeFilters.add(new AnnotationTypeFilter(
                    ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
            logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
        }
        catch (ClassNotFoundException ex) {
        }
        try {
            //添加Named注解
            this.includeFilters.add(new AnnotationTypeFilter(
                    ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
            logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
        }
        catch (ClassNotFoundException ex) {
        }
    }
    
    //掃描basePackages下使用注解的類
    public int scan(String... basePackages) {
        //DefaultListableBeanFactory#getBeanDefinitionCount()
        //獲取beanDefinitionMap元素的數(shù)量
        //beanDefinitionMap = new ConcurrentHashMap<>(256);
        int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
    
        //掃描方法
        doScan(basePackages);

        //默認為true
        if (this.includeAnnotationConfig) {
            //該方法實例化reader的時候已經(jīng)執(zhí)行過一次了
            AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
        }
        
        //返回實際掃描的數(shù)量
        return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
    }
    
    //掃描方法
    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) {
            //掃描到Compent注解的bean列表
            Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
            for (BeanDefinition candidate : candidates) {
                //獲取Scope注解的值
                ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                candidate.setScope(scopeMetadata.getScopeName());
                //生成bean名稱
                String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                if (candidate instanceof AbstractBeanDefinition) {
                    //bean默認配置
                    postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
                }
                if (candidate instanceof AnnotatedBeanDefinition) {
                    //配置bean
                    AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
                }
                if (checkCandidate(beanName, candidate)) {
                    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                    definitionHolder =
                            AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                    beanDefinitions.add(definitionHolder);
                    //注冊bean
                    registerBeanDefinition(definitionHolder, this.registry);
                }
            }
        }
        return beanDefinitions;
    }
}

8. 總結(jié)

實例化AnnotationConfigServletWebServerApplicationContext過程中, 會先調(diào)用父類GenericApplicationContext構(gòu)造函數(shù), 實例化了一個DefaultListableBeanFactory, 作為Spring IOC容器, AnnotationConfigServletWebServerApplicationContext的構(gòu)造函數(shù)實例化了AnnotatedBeanDefinitionReader對象, 用于讀取Spring的bean定義, 在實例化AnnotatedBeanDefinitionReader的過程中, 注冊了幾個bean, 用來處理相應(yīng)的注解

下一篇

我們將會在下一篇SpringBootExceptionReporter異常上報, 繼續(xù)閱讀springboot源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恨狈,一起剝皮案震驚了整個濱河市疏哗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌禾怠,老刑警劉巖返奉,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吗氏,居然都是意外死亡芽偏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門弦讽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來污尉,“玉大人,你說我怎么就攤上這事往产”煌耄” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵仿村,是天一觀的道長锐朴。 經(jīng)常有香客問我,道長蔼囊,這世上最難降的妖魔是什么焚志? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮畏鼓,結(jié)果婚禮上酱酬,老公的妹妹穿的比我還像新娘。我一直安慰自己云矫,他們只是感情好岳悟,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般贵少。 火紅的嫁衣襯著肌膚如雪呵俏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天滔灶,我揣著相機與錄音普碎,去河邊找鬼。 笑死录平,一個胖子當著我的面吹牛麻车,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播斗这,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼动猬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了表箭?” 一聲冷哼從身側(cè)響起赁咙,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎免钻,沒想到半個月后彼水,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡极舔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年凤覆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拆魏。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡盯桦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渤刃,到底是詐尸還是另有隱情拥峦,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布溪掀,位于F島的核電站事镣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏揪胃。R本人自食惡果不足惜璃哟,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喊递。 院中可真熱鬧随闪,春花似錦、人聲如沸骚勘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至当宴,卻和暖如春畜吊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背户矢。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工玲献, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人梯浪。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓捌年,卻偏偏與公主長得像,于是被迫代替她去往敵國和親挂洛。 傳聞我的和親對象是個殘疾皇子礼预,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan閱讀 4,159評論 2 7
  • spring源碼分析(二) 目錄五、Spring 源碼解讀--5.1虏劲、什么是IOC/DI--5.2托酸、Spring ...
    毛子果閱讀 401評論 0 0
  • 點燃一支香,煙如一支射出的箭伙单,直至無跡而化获高,香味便若有若無飄出來…… 人都難免自命不凡哈肖,那是沒見過高山吻育。最近兩年在...
    夏曉勇閱讀 141評論 0 1
  • 我叫小柒币狠,90后游两,廣西人,愛生活漩绵,愛旅行贱案。曾經(jīng)不拘放縱愛自由的我,有一個夢想就是希望能遇見同路的朋友止吐,聽他同路而又...
    90小柒閱讀 334評論 26 4
  • 前幾天讀梁羽生散文宝踪,他在文中提及自己寫作武俠小說《云海玉弓緣》的一些事,勾起了我久遠的回憶碍扔。 讀初中那會兒瘩燥,港臺武...
    葉辰秋閱讀 278評論 0 3