Spring提供多种扫描注入方式,包+注解扫描,xml配置文件扫描等,其原理相似
本文以如下demo为例,Spring版本为5.3.7
public static void main(String[] args) {
AbstractApplicationContext ac = new AnnotationConfigApplicationContext("com.zsx.bean");
}
@Component
public class Hello {
public void say() {
System.out.println("Hello");
}
}
概念介绍
instance
:java通过调用其构造方法生成的对象spring bean
:经过Spring
生命周期加载过的instance
beanDefinetion
: 存在未生成Spring bean
时的该bean
的相关参数,包括不限于描述,是否单例等信息singletonObjects
: 单例池/一级缓存,所有spring
单例对象的容器,也是通常所说的spring
容器BeanFactory
: 是一个工厂类(接口), 它负责生产和管理bean的一个工厂,是ioc 容器最底层的接口FactoryBean
:是一个可以生产对象和装饰对象的工厂bean
源码解读:
- 通过
new AnnotationConfigApplicationContext("com.zsx.bean");
调用org.springframework.context.support.AbstractApplicationContext
的构造方法
public AnnotationConfigApplicationContext(String... basePackages) {
this();
//包扫描,将对应包内@Component注解的对象转换成beanDefinetion对象
//封装到(beanName,beanDefinetion)的registry-->beanFactory-->beanDefinitionMap中
scan(basePackages);
//属性为单例的beanDefinetion生成单例放入单例池
refresh();
}
scan(basePackages);
解读
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
//1. getApplicationStartup() --> 创建名 为‘spring.context.base-packages.scan’的 DefaultApplicationStartup 作用为追踪相关指标
//2. tag() --> 校验了一个 recorded 变量,意味着是否记录过相关变量,初始为false, true则抛出异常
StartupStep scanPackages = this.getApplicationStartup().start("spring.context.base-packages.scan")
.tag("packages", () -> Arrays.toString(basePackages));
// 扫描包
this.scanner.scan(basePackages);
//this.recorded = true; --> 防止再次扫描
scanPackages.end();
}
scan(basePackages);--> this.scanner.scan(basePackages);
解读
public int scan(String... basePackages) {
// 获取扫描之前 BeanDefinition 的个数,也就是Spring自带的BeanDefinition 个数
// BeanDefinition --> Spring所有的bean在开始生命周期时候存放的位置,包含了bean的描述,是否懒加载等相关信息
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
// 包扫描并加入 this.registry
doScan(basePackages);
// Register annotation config processors, if necessary.
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
// 返回本次包扫描所加载的BeanDefinition的数量
// 本次扫描多出的BeanDefinition,就是本地服务 basePackages包内,加上@Component的类
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
-
scan(basePackages);--> this.scanner.scan(basePackages);--> doScan(basePackages);
解读扫描多个包底下的类,封装成beanDefinitions并注册到registry仓库中
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
// basePackages可以是数组,支持多个包的扫描
for (String basePackage : basePackages) {
// 获取basePackage 下所有带@component的类
// 相关信息封装成 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);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// this.registry中加入该 definitionHolder
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
-
refresh();
解读加载的registry中的beanDefinitions…
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 设置了启动日期等一些初始化动作
prepareRefresh();
// 刷新 beanFactory ,设置序列化ID
// 这时候的beanFactory 中的 beanDefinitionMap 属性已经存在 @component注解的相关类+Spring自带的bean,在scan()方法时就已经加入
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 初始化beanFactory的配置类加载器以及一些后置处理器
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后处理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 调用后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截bean创建的bean处理器。
registerBeanPostProcessors(beanFactory);
// this.recorded = true;
// 防止重复初始化
beanPostProcess.end();
// 初始化上下文的消息源 messageSource
initMessageSource();
// 初始化上下文的事件 applicationEventMulticaster
initApplicationEventMulticaster();
// 初始化特殊的bean
onRefresh();
// 注册监听器
registerListeners();
// 实例化非懒加载 单例的bean -->
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建的bean
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
refresh();--> finishBeanFactoryInitialization(beanFactory);
完成上下文bean工厂的初始化
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化类型转换的服务
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 初始化一个默认的嵌入式值解析器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 尽早初始化LoadTimeWeaverAware bean,以允许尽早注册它们的转换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// 冻结所有bean定义
beanFactory.freezeConfiguration();
// 初始化所以非懒加载的单例.
beanFactory.preInstantiateSingletons();
}
-
refresh();--> finishBeanFactoryInitialization(beanFactory);-->beanFactory.preInstantiateSingletons();
初始化所有非懒加载的单例核心是
getBean(beanName);
public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // 触发 非懒加载的bean的初始化 for (String beanName : beanNames) { // 通过beanName获取对应的 BeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 单例且不是懒加载 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { // 被实例化单例池中&&不存在BeanDefinition的Map对象中 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { getBean(beanName); } } } // 触发所有适用bean的初始化后回调。... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize") .tag("beanName", beanName); SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } smartInitialize.end(); } }}
refresh();--> finishBeanFactoryInitialization(beanFactory);-->beanFactory.preInstantiateSingletons();--> getBean(beanName);
@Overridepublic Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false);}
protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object beanInstance; // 单例池中获取 bean // 第一次进来:sharedInstance==null --> 单例池中不存在这个bean && bean不在 正在创建的bean的列表 中 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } // alreadyCreated todo if (!typeCheckOnly) { markBeanAsCreated(beanName); } StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate") .tag("beanName", name); try { if (requiredType != null) { beanCreation.tag("beanType", requiredType::toString); } RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // 保证初始化当前bean所依赖的bean。 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // scope是单例--> 创建一个bean的实例对象 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { // 本质是构造器的createInstance()方法创建了对象 return createBean(beanName, mbd, args); } catch (BeansException ex) { //从单例缓存中移除实例 //创建过程中,允许循环引用解析。 //同时删除所有接收到临时引用的bean。 destroySingleton(beanName); throw ex; } }); beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // 原型模式--> TODO else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean ?" + beanName + "'"); } Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new ScopeNotActiveException(beanName, scopeName, ex); } } } catch (BeansException ex) { beanCreation.tag("exception", ex.getClass().toString()); beanCreation.tag("message", String.valueOf(ex.getMessage())); cleanupAfterBeanCreationFailure(beanName); throw ex; } finally { beanCreation.end(); } } return adaptBeanInstance(name, beanInstance, requiredType);}
-
第一次进来获取单例
Object sharedInstance = getSingleton(beanName);
由于第一次进来,
isSingletonCurrentlyInCreation(beanName)
是false,所以没有走到下面的方法。从而去获取了单例实例
public Object getSingleton(String beanName) { return getSingleton(beanName, true);}
/** * 获取单例bean对象 * singletonObjects --> 一级缓存,单例池,也就是通常所说的Spring容器,所有单例的bean都是从中获取对象 * earlySingletonObjects --> 二级缓存,避免一个bean被多个bean依赖,而出现多次调用工厂的情况 * singletonFactories --> 三级缓存,工厂代理,其中包含了生成bean的过程。 * * @param beanName * @param allowEarlyReference * @return */@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) { // 通过beanName去一级缓存(单例池)中获取对象 Object singletonObject = this.singletonObjects.get(beanName); // 对象为空 && beanName的这个bean正在创建过程中 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 通过beanName去二级缓存中获取对象 singletonObject = this.earlySingletonObjects.get(beanName); // 二级缓存不存在对象且 该beanName所对应的beanDefinetion中的allowEarlyReference (支持循环依赖)为true if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { // 单例模式-锁双重判断 singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { // 二级缓存再去获取一次对象 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { // 最终去三级缓存,工厂中去生成对象 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); // 放入二级缓存 this.earlySingletonObjects.put(beanName, singletonObject); // TODO this.singletonFactories.remove(beanName); } } } } } } return singletonObject;}
- 获取单例对象方法
sharedInstance = getSingleton(beanName, () -> { try { // 本质是构造器的createInstance()方法创建了对象 return createBean(beanName, mbd, args); } catch (BeansException ex) { //从单例缓存中移除实例 //创建过程中,允许循环引用解析。 //同时删除所有接收到临时引用的bean。 destroySingleton(beanName); throw ex; }
refresh();--> fini0shBeanFactoryInitialization(beanFactory);-->beanFactory.preInstantiateSingletons();--> getBean(beanName);--> doGetBean(name, null, null, false);--> getSingleton()
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { //单例池获取对象 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } //创建单例对象前执行的方法 // 该对象放入singletonsCurrentlyInCreation容器,表明该对象正在创建中 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { //参数传入的单例构造工厂获取单例对象 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } //新建的单例对象 --> 存入单例池(一级缓存,也就是常说的Spring 容器) 以及某些其他缓存 if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; }}
-
主要流程如下:
① 项目启动时,扫描配置好的包名,将对应包下的
@Component
注解的类以key=beanName,value=BeanDefinetion
的形式加入registry
② 解析
registry
,通过BeanDefinetion
的信息判断是否是单例,是则获取对应的实例,并存入单例池singletonObjects
中