上篇回顧
上一篇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前綴:
- beanFactory設(shè)置AnnotationAwareOrderComparator
- 處理Ordered類酝碳、@Order注解和@Priority
- 處理完成之后排序
- beanFactory設(shè)置ContextAnnotationAutowireCandidateResolver
- 處理@Lazy注解
- 配置延遲加載
- 注冊ConfigurationClassPostProcessor類型的bean
- 處理@Configuration注解
- 非常重要的一個類
- bean名稱為internalConfigurationAnnotationProcessor
- 注冊AutowiredAnnotationBeanPostProcessor類型的bean
- 處理@Autowired, @Value注解
- bean名稱為internalAutowiredAnnotationProcessor
- 注冊CommonAnnotationBeanPostProcessor類型的bean
- 處理@PostConstruct,@PreDestroy注解
- bean名稱為internalCommonAnnotationProcessor
- 注冊EventListenerMethodProcessor類型的bean
- 處理@EventListener注解
- bean名稱為internalEventListenerProcessor
- 注冊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源碼