refresh() -> finishBeanFactoryInitialization()
初始化剩下的单实例(非懒加载的)
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 为上下文初始化类型转换器
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));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 尽早初始化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);
// Allow for caching all bean definition metadata, not expecting further changes.
// 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化剩下的单例对象
beanFactory.preInstantiateSingletons();
}
1.为上下文初始化类型转换器
ConversionService
转换服务:如未设置则没有该转换服务对象,如配置了,则默认为DefaultConversionService
引入方式
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean"/>
可以在ConversionServiceFactoryBean
实例中引入自定义的转换对象
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="example.MyCustomConverter"/>
</set>
</property>
</bean>
DefaultConversionService
默认设置了52种转换方式,有一对一的转换,一对多的转换,多对多的转换,分别如下
-
一转一:实现
Converter
接口public interface Converter<S, T> { // 将S类型转换成T类型 T convert(S source); }
-
一转多:实现
GenericConverter
接口(用于两种或者更多种类型之间转换的通用转换器接口)// 转换源对象到目标类型的描述 Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType)
-
多转多:实现
ConverterFactory
接口(converter
转换器的工厂类,用来获取对应的转换器)public interface ConverterFactory<S, R> { // 获取转换器 <T extends R> Converter<S, T> getConverter(Class<T> targetType); }
-
ConditionalConverter:根据
source
和target
来做条件判断,从而判断哪个转换器生效哪个转换器不生效boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
2.判断beanFactory之前没有注册嵌入值解析器,没有则注册
PropertyPlaceholderConfigurer
主要用于注解属性值的解析
通常在invokeBeanFactoryPostProcessors()
方法中就已经注册了,所以这里无需再注册
3.初始化loadTimeWeaverAware bean
// 默认没有
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
在AOP
部分详细讲解
4.禁止使用临时类加载器进行类型匹配
设置BeanFactory
的tempClassLoader
属性为null
public void setTempClassLoader(@Nullable ClassLoader tempClassLoader) {
this.tempClassLoader = tempClassLoader;
}
5.冻结所有的bean定义
设置BeanFactory
的configurationFrozen
属性为true
,且赋值属性frozenBeanDefinitionNames
字符数组为BeanFactory
中的beanDefinitionNames
属性值
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
备注:此处说明注册的bean定义将不被修改或任何进一步的处理
6.实例化剩下的单例对象
beanFactory.preInstantiateSingletons();
DefaultListableBeanFactory
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.
// 将所有BeanDefinition的名字创建一个集合
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 触发所有非延迟加载单例bean的初始化,遍历集合的对象
for (String beanName : beanNames) {
// 合并父类BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 条件判断,抽象,单例,非懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断是否实现了FactoryBean接口
if (isFactoryBean(beanName)) {
// 根据&+beanName来获取具体的对象
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// 进行类型转换
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
// 判断这个FactoryBean是否希望立即初始化
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());
}
// 如果希望急切的初始化,则通过beanName获取bean实例
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
for (String beanName : beanNames) {
// 获取beanName对应的bean实例
Object singletonInstance = getSingleton(beanName);
// 判断singletonInstance是否实现了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
// 类型转换
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
// 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
getMergedLocalBeanDefinition
在实例化之前,要把所有的基础的BeanDefinition
对象转换成RootBeanDefinition
对象,进行缓存,后续在需要马上要实例化的时候,直接获取定义信息,而定义信息中如果包含了父类,那么必须要先创建父类才能有子类
// 获取beanName合并后的本地RootBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 首先以最小的锁定快速检测并发映射。
// 从bean名称映射到合并的RootBeanDefinition的集合中获取beanName对应的RootBeanDefinition
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
// 如果mbd不为null 且 不需要重新合并定义
if (mbd != null && !mbd.stale) {
// 返回对应的RootBeanDefinition
return mbd;
}
// 获取beanName对应的合并Bean定义,如果beanName对应的BeanDefinition是子BeanDefinition,
// 则通过与父级合并返回RootBeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
mergedBeanDefinitions
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
该集合对象前期部分BeanDefinition
对象由于场景需要已经合并为了RootBeanDefinition
对象且缓存到了该集合中,如:refresh() -> invokeBeanFactoryPostProcessors()
- org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
- org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanNamesForType
- org.springframework.beans.factory.support.DefaultListableBeanFactory#doGetBeanNamesForType
- org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
isFactoryBean
确定name
的Bean
是否为FactoryBean
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
//去除name开头的'&'字符,获取name最终的规范名称【最终别名或者是全类名】:
String beanName = transformedBeanName(name);
//获取beanName注册的(原始)单例对象,如果单例对象没有找到,并且beanName存在
// 正在创建的Set集合中
Object beanInstance = getSingleton(beanName, false);
//如果beanInstance能获取到
if (beanInstance != null) {
// 如果 beanInstance是FactoryBean的实例 则返回true,否则返回false。
return (beanInstance instanceof FactoryBean);
}
// No singleton instance found -> check bean definition.
// 如果缓存中不存在此beanName && 父beanFactory是ConfigurableBeanFactory,则调用父BeanFactory判断是否为FactoryBean
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
// 在该工厂中找不到bean定义 -> 委托给父对象
// 尝试在父工厂中确定name是否为FactoryBean,如果不是返回false,否则返回true【递归】
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
// 如果该bean对应于子bean定义,则遍历父bean定义。
// 判断(beanName和beanName对应的合并后BeanDefinition)所指的bean是否FactoryBean并将结果返回出去
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
isFactoryBean
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
// 定义一个存储mbd是否是FactoryBean的标记
Boolean result = mbd.isFactoryBean;
// 如果没有配置mbd的工厂Bean
if (result == null) {
// 根据预测指定bean的最终bean类型
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
// 如果成功获取最终bean类型,且最终bean类型属于FactoryBean类型
result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
// 将result缓存在mbd中
mbd.isFactoryBean = result;
}
// 如果不为空,直接返回
return result;
}
getBean
此方法不仅在此处会调用,在执行finishBeanFactoryInitialization()
方法前就已经调用过。如:invokeBeanFactoryPostProcessors()
中就调用该方法进行对象的实例化
实例化简要概述
- getBean
- doGetBean:此方法是实际获取bean的方法,也是触发依赖注入的方法
- createBean
- doCreateBean
doGetBean
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
/**
* 提取对应的beanName,很多同学可能会认为此处直接使用即可,为什么还要进行转换呢,原因在于当bean对象实现FactoryBean接口之后就会变成&beanName,同时如果存在别名,也需要把别名进行转换*/
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
/**提前检查单例缓存中是否有手动注册的单例对象,跟循环依赖有关联*/
Object sharedInstance = getSingleton(beanName);
// 如果bean的单例对象找到了,且没有创建bean实例时要使用的参数
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 + "'");
}
}
// 返回对象的实例,很多同学会理解不了这句话存在的意义,当你实现了FactoryBean接口的对象,需要获取具体的对象的时候就需要此方法来进行获取了
bean = 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.
// 如果bean定义不存在,就检查父工厂是否有
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName,那么就尝试从父容器中获取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】
String nameToLookup = originalBeanName(name);
// 如果父工厂是AbstractBeanFactory的实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 调用父工厂的doGetBean方法,就是该方法。【递归】
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
// 如果有创建bean实例时要使用的参数
// Delegation to parent with explicit args. 使用显示参数委派给父工厂
// 使用父工厂获取该bean对象,通bean全类名和创建bean实例时要使用的参数
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
// 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。
// 使用父工厂获取该bean对象,通bean全类名和所需的bean类型
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 使用父工厂获取bean,通过bean全类名
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 如果不是做类型检查,那么表示要创建bean,此处在集合中做一个记录
if (!typeCheckOnly) {
// 为beanName标记为已经创建(或将要创建)
markBeanAsCreated(beanName);
}
try {
// 此处做了BeanDefinition对象的转换,当我们从xml文件中加载beandefinition对象的时候,封装的对象是GenericBeanDefinition,
// 此处要做类型转换,如果是子类bean的话,会合并父类的相关属性
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查mbd的合法性,不合格会引发验证异常
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 如果存在依赖的bean的话,那么则优先实例化依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 如果存在依赖,则需要递归实例化依赖的bean
for (String dep : dependsOn) {
// 如果beanName已注册依赖于dependentBeanName的关系
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册各个bean的依赖关系,方便进行销毁
registerDependentBean(dep, beanName);
try {
// 递归优先实例化被依赖的Bean
getBean(dep);
}
// 捕捉为找到BeanDefinition异常:'beanName'依赖于缺少的bean'dep'
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 创建bean的实例对象
if (mbd.isSingleton()) {
// 返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:
sharedInstance = getSingleton(beanName, () -> {
try {
// 为给定的合并后BeanDefinition(和参数)创建一个bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
// 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除
// 接收到该Bean临时引用的任何Bean
// 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
destroySingleton(beanName);
// 重新抛出ex
throw ex;
}
});
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 原型模式的bean对象创建
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
// 它是一个原型 -> 创建一个新实例
// 定义prototype实例
Object prototypeInstance = null;
try {
// 创建Prototype对象前的准备工作,默认实现将beanName添加到prototypesCurrentlyInCreation中
beforePrototypeCreation(beanName);
// 为mbd(和参数)创建一个bean实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除
afterPrototypeCreation(beanName);
}
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 指定的scope上实例化bean
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
// 从scopes中获取scopeName对于的Scope对象
Scope scope = this.scopes.get(scopeName);
// 如果scope为null
if (scope == null) {
// 抛出非法状态异常:没有名为'scopeName'的scope注册
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 从scope中获取beanName对应的实例对象
Object scopedInstance = scope.get(beanName, () -> {
// 创建Prototype对象前的准备工作,默认实现 将beanName添加到prototypesCurrentlyInCreation中
beforePrototypeCreation(beanName);
try {
// 为mbd(和参数)创建一个bean实例
return createBean(beanName, mbd, args);
}
finally {
// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除
afterPrototypeCreation(beanName);
}
});
// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
// FactoryBean会直接返回beanInstance实例
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
// 捕捉非法状态异常
// 抛出Bean创建异常:作用域 'scopeName' 对于当前线程是不活动的;如果您打算从单个实例引用它,请考虑为此
// beanDefinition一个作用域代理
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
// 捕捉获取Bean对象抛出的Bean异常
// 在Bean创建失败后,对缓存的元数据执行适当的清理
cleanupAfterBeanCreationFailure(beanName);
// 重新抛出ex
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 检查requiredType是否与实际Bean实例的类型匹配
// 如果requiredType不为null&&bean不是requiredType的实例
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 获取此BeanFactory使用的类型转换器,将bean转换为requiredType
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
// 如果convertedBean为null
if (convertedBean == null) {
// 抛出Bean不是必要类型的异常
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
// 返回convertedBean
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
// 将bean返回出去
return (T) bean;
}
getDependsOn
如果存在依赖的bean
的话,那么则优先实例化依赖的bean
;如:
<bean id="a" class="com.armin.self_editor.Customer" depends-on="b"/>
<bean id="b" class="com.armin.self_aware.MyAwareProcessor"/>
depends-on
属性值为需要优先实例化的依赖bean
getSingleton
返回以给定名称注册的(原始)单例对象,如果尚未注册,则创建并注册一个对象
Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)
此处只有在getSingleton()
中调用ObjectFactory
对象的的getObject()
方法时才会执行如下匿名内部内的业务逻辑createBean()
sharedInstance = getSingleton(beanName, () -> {
try {
// 为给定的合并后BeanDefinition(和参数)创建一个bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除
// 接收到该Bean临时引用的任何Bean
// 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
destroySingleton(beanName);
// 重新抛出ex
throw ex;
}
});
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
// 如果beanName为null,抛出异常
Assert.notNull(beanName, "Bean name must not be null");
// 使用单例对象的高速缓存Map作为锁,保证线程同步
synchronized (this.singletonObjects) {
// 从单例对象的高速缓存Map中获取beanName对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 如果单例对象获取不到
if (singletonObject == null) {
// 如果当前在destorySingletons中
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 + "'");
}
// 创建单例之前的回调,默认实现将单例注册为当前正在创建中
beforeSingletonCreation(beanName);
// 表示生成了新的单例对象的标记,默认为false,表示没有生成新的单例对象
boolean newSingleton = false;
// 有抑制异常记录标记,没有时为true,否则为false
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
// 如果没有抑制异常记录
if (recordSuppressedExceptions) {
// 对抑制的异常列表进行实例化(LinkedHashSet)
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 从单例工厂中获取对象
singletonObject = singletonFactory.getObject();
// 生成了新的单例对象的标记为true,表示生成了新的单例对象
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.
// 同时,单例对象是否隐式出现 -> 如果是,请继续操作,因为异常表明该状态
// 尝试从单例对象的高速缓存Map中获取beanName的单例对象
singletonObject = this.singletonObjects.get(beanName);
// 如果获取失败,抛出异常
if (singletonObject == null) {
throw ex;
}
}
// 捕捉Bean创建异常
catch (BeanCreationException ex) {
// 如果没有抑制异常记录
if (recordSuppressedExceptions) {
// 遍历抑制的异常列表
for (Exception suppressedException : this.suppressedExceptions) {
// 将抑制的异常对象添加到 bean创建异常 中,这样做的,就是相当于 '因XXX异常导致了Bean创建异常‘ 的说法
ex.addRelatedCause(suppressedException);
}
}
// 抛出异常
throw ex;
}
finally {
// 如果没有抑制异常记录
if (recordSuppressedExceptions) {
// 将抑制的异常列表置为null,因为suppressedExceptions是对应单个bean的异常记录,置为null
// 可防止异常信息的混乱
this.suppressedExceptions = null;
}
// 创建单例后的回调,默认实现将单例标记为不在创建中
afterSingletonCreation(beanName);
}
// 生成了新的单例对象
if (newSingleton) {
// 将beanName和singletonObject的映射关系添加到该工厂的单例缓存中:
addSingleton(beanName, singletonObject);
}
}
// 返回该单例对象
return singletonObject;
}
}
remark
singletonObjects:一级缓存
beforeSingletonCreation:创建单例之前的回调
protected void beforeSingletonCreation(String beanName) { // 如果当前在创建检查中的排除bean名列表中不包含该beanName且将beanName添加到当前正在创建的bean名称列表后,出现 // beanName已经在当前正在创建的bean名称列表中添加过 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { // 抛出当前正在创建的Bean异常 throw new BeanCurrentlyInCreationException(beanName); } }
singletonFactory.getObject():实际的创建
bean
的方法指向的是上述匿名内部类中的createBean()
createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 锁定class,根据设置的class属性或者根据className来解析class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 进行条件筛选,重新赋值RootBeanDefinition,并设置BeanClass属性
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 重新创建一个RootBeanDefinition对象
mbdToUse = new RootBeanDefinition(mbd);
// 设置BeanClass属性值
mbdToUse.setBeanClass(resolvedClass);
}
// 验证及准备覆盖的方法,lookup-method replace-method,当需要创建的bean对象中包含了lookup-method和replace-method标签的时候,会产生覆盖操作
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 给BeanPostProcessors一个机会来返回代理来替代真正的实例,应用实例化前的前置处理器,用户自定义动态代理的方式,针对于当前的被代理类需要经过标准的代理流程来创建对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 实际创建bean的调用
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
remark
resolveBeanClass:为指定的
bean
定义解析bean
类,将bean
类名解析为Class
引用(如果需要),并将解析后的Class
存储在bean
定义中以备将来使用protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch) throws CannotLoadBeanClassException { try { // 判断mbd的定义信息中是否包含beanClass,并且是Class类型的,如果是直接返回,否则的话进行详细的解析 if (mbd.hasBeanClass()) { // 如果mbd指定了bean类 return mbd.getBeanClass(); } // 判断是否有安全管理器(jdbc中的DriverManager中loadInitialDrivers一致,doPrivileged是一个本地方法) if (System.getSecurityManager() != null) { return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); } else { // 进行详细的处理解析过程 return doResolveBeanClass(mbd, typesToMatch); } } catch (PrivilegedActionException pae) { ClassNotFoundException ex = (ClassNotFoundException) pae.getException(); throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (ClassNotFoundException ex) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (LinkageError err) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err); } }
doResolveBeanClass:获取
mbd
配置的bean
类名,将bean
类名解析为Class
对象,并将解析后的Class
对象缓存在mdb
中以备将来使用private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException { // 获取该工厂的加载bean用的类加载器 ClassLoader beanClassLoader = getBeanClassLoader(); // 初始化动态类加载器为该工厂的加载bean用的类加载器,如果该工厂有 // 临时类加载器器时,该动态类加载器就是该工厂的临时类加载器 ClassLoader dynamicLoader = beanClassLoader; // 表示mdb的配置的bean类名需要重新被dynameicLoader加载的标记,默认不需要 boolean freshResolve = false; //如果有传入要匹配的类型 if (!ObjectUtils.isEmpty(typesToMatch)) { // 仅进行类型检查时(即尚未创建实际实例),请使用指定的临时类加载器 // 获取该工厂的临时类加载器,该临时类加载器专门用于类型匹配 ClassLoader tempClassLoader = getTempClassLoader(); // 如果成功获取到临时类加载器 if (tempClassLoader != null) { // 以该工厂的临时类加载器作为动态类加载器 dynamicLoader = tempClassLoader; // 标记mdb的配置的bean类名需要重新被dynameicLoader加载 freshResolve = true; // DecoratingClassLoader:装饰ClassLoader的基类,提供对排除的包和类的通用处理 // 如果临时类加载器是DecoratingClassLoader的基类 if (tempClassLoader instanceof DecoratingClassLoader) { // 将临时类加载器强转为DecoratingClassLoader实例 DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader; // 对要匹配的类型进行在装饰类加载器中的排除,以交由父ClassLoader以常规方式处理 for (Class<?> typeToMatch : typesToMatch) { dcl.excludeClass(typeToMatch.getName()); } } } } // 从mbd中获取配置的bean类名 String className = mbd.getBeanClassName(); // 如果能成功获得配置的bean类名 if (className != null) { //评估benaDefinition中包含的className,如果className是可解析表达式,会对其进行解析,否则直接返回className: Object evaluated = evaluateBeanDefinitionString(className, mbd); // 判断className是否等于计算出的表达式的结果,如果不等于,那么判断evaluated的类型 if (!className.equals(evaluated)) { // A dynamically resolved expression, supported as of 4.2... // 如果evaluated属于Class实例 if (evaluated instanceof Class) { // 强转evaluatedw为Class对象并返回出去 return (Class<?>) evaluated; } // 如果evaluated属于String实例 else if (evaluated instanceof String) { // 将evaluated作为className的值 className = (String) evaluated; // 标记mdb的配置的bean类名需要重新被dynameicLoader加载 freshResolve = true; } else { // 抛出非法状态异常:无效的类名表达式结果:evaluated throw new IllegalStateException("Invalid class name expression result: " + evaluated); } } // 如果mdb的配置的bean类名需要重新被dynameicLoader加载 if (freshResolve) { // 当使用临时类加载器进行解析时,请尽早退出以避免将已解析的类存储在BeanDefinition中 // 如果动态类加载器不为null if (dynamicLoader != null) { try { // 使用dynamicLoader加载className对应的类型,并返回加载成功的Class对象 return dynamicLoader.loadClass(className); } // 捕捉未找到类异常, catch (ClassNotFoundException ex) { if (logger.isTraceEnabled()) { logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex); } } } // 使用classLoader加载name对应的Class对象,该方式是Spring用于代替Class.forName()的方法,支持返回原始的类实例(如'int') // 和数组类名 (如'String[]')。此外,它还能够以Java source样式解析内部类名(如:'java.lang.Thread.State' // 而不是'java.lang.Thread$State') return ClassUtils.forName(className, dynamicLoader); } } // 定期解析,将结果缓存在BeanDefinition中... // 使用classLoader加载当前BeanDefinitiond对象所配置的Bean类名的Class对象(每次调用都会重新加载,可通过 // AbstractBeanDefinition#getBeanClass 获取缓存) return mbd.resolveBeanClass(beanClassLoader); }
resolveBeanClass
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException { // 获取className String className = getBeanClassName(); if (className == null) { return null; } // 获取当前bean对应的Class对象 Class<?> resolvedClass = ClassUtils.forName(className, classLoader); this.beanClass = resolvedClass; return resolvedClass; }
ClassUtils.forName:使用
classLoader
加载name
对应的Class
对象public static Class<?> forName(String name, @Nullable ClassLoader classLoader) throws ClassNotFoundException, LinkageError { // 如果name为null,抛出异常 Assert.notNull(name, "Name must not be null"); // 如果name是个原始类型名,就获取其对应的Class Class<?> clazz = resolvePrimitiveClassName(name); // 如果clazz为null if (clazz == null) { // 从缓存Map中获取name对应的Class clazz = commonClassCache.get(name); } // 如果clazz不为null if (clazz != null) { // 直接返回clazz return clazz; } // "java.lang.String[]" style arrays // "java.lang.String[]" style arrays 'java.lang.String[]'样式数组,表示原始数组类名 // 如果name是以'[]'结尾的 if (name.endsWith(ARRAY_SUFFIX)) { // 截取出name'[]'前面的字符串赋值给elementClassName String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length()); // 传入elementClassName递归本方法获取其Class Class<?> elementClass = forName(elementClassName, classLoader); // 新建一个elementClass类型长度为0的数组,然后获取其类型返回出去 return Array.newInstance(elementClass, 0).getClass(); } // "[Ljava.lang.String;" style arrays // 如果names是以'[L'开头且以';'结尾 if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) { // 截取出name'[L'到';'之间的字符串赋值给elementName String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1); // 传入elementName递归本方法获取其Class Class<?> elementClass = forName(elementName, classLoader); // 新建一个elementClass类型长度为0的数组,然后获取其类型返回出去 return Array.newInstance(elementClass, 0).getClass(); } // "[[I" or "[[Ljava.lang.String;" style arrays // "[[I" or "[[Ljava.lang.String;" style arrays '[[I' 或者 '[[Ljava.lang.String;'样式数组,表示内部数组类名 if (name.startsWith(INTERNAL_ARRAY_PREFIX)) { // 截取出name '['后面的字符串赋值给elementName String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length()); // 传入elementName递归本方法获取其Class Class<?> elementClass = forName(elementName, classLoader); // 新建一个elementClass类型长度为0的数组,然后获取其类型返回出去 return Array.newInstance(elementClass, 0).getClass(); } // 将classLoader赋值给clToUse变量 ClassLoader clToUse = classLoader; // 如果clToUse为null if (clToUse == null) { // 获取默认类加载器,一般返回线程上下文类加载器,没有就返回加载ClassUtils的类加载器, // 还是没有就返回系统类加载器,最后还是没有就返回null clToUse = getDefaultClassLoader(); } try { // 返回与给定的字符串名称相关联类或接口的Class对象。 return Class.forName(name, false, clToUse); } catch (ClassNotFoundException ex) { // 如果找到不到类时 // 获取最后一个包名分割符'.'的索引位置 int lastDotIndex = name.lastIndexOf(PACKAGE_SEPARATOR); // 如果找到索引位置 if (lastDotIndex != -1) { // 尝试将name转换成内部类名,innerClassName=name的包名+'$'+name的类名 String innerClassName = name.substring(0, lastDotIndex) + INNER_CLASS_SEPARATOR + name.substring(lastDotIndex + 1); try { // 通过clToUse获取innerClassName对应的Class对象 return Class.forName(innerClassName, false, clToUse); } catch (ClassNotFoundException ex2) { // Swallow - let original exception get through } } // 当将name转换成内部类名仍然获取不到Class对象时,抛出异常 throw ex; } }
lookup-method:解决了单利引用了原型模式(每次获取新的对象)
Spring
中默认的对象都是单例的,Spring
会在一级缓存中持有该对象,方便下次直接获取。那么如果是原型作用域(scope="prototype"
)的话,会创建一个新的对象。如果想在一个单例模式的bean
下引用一个原型模式的bean
怎么办?在此时就需要引用
lookup-method
标签来解决此问题通过拦截器的方式每次需要的时候都去创建最新的对象,而不会把原型对象缓存起来
replaced-method:任意方法替换
OriginalDog:将要被替换的方法(此处方法重载)
public class OriginalDog { public void sayHello() { System.out.println("Hello,I am a black dog..."); } public void sayHello(String name) { System.out.println("Hello,I am a black dog, my name is " + name); } }
ReplaceDog
import org.springframework.beans.factory.support.MethodReplacer; import java.lang.reflect.Method; import java.util.Arrays; public class ReplaceDog implements MethodReplacer { @Override public Object reimplement(Object obj, Method method, Object[] args) throws Throwable { System.out.println("real execute method"); Arrays.stream(args).forEach(System.out::print); return obj; } }
armin-self-method-overrides.xml
<bean id="originalDog" class="com.armin.method_overrides.replace.OriginalDog"> <replaced-method name="sayHello" replacer="replaceDog"> <arg-type match="Str"/> </replaced-method> </bean> <bean id="replaceDog" class="com.armin.method_overrides.replace.ReplaceDog"/>
<arg-type match="Str"/>
有多种写法,如:match
=java.lang.String
,String
或``Str`在元素中使用一个或多个
<arg-type/>
元素<replaced-method/>
来指示被覆盖的方法的方法签名。只有当方法被重载并且类中存在多个变体时,参数的签名才是必需的。为方便起见,参数的类型字符串可以是完全限定类型名称的子字符串。Test
import com.armin.method_overrides.replace.OriginalDog; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) throws Throwable { ApplicationContext context = new ClassPathXmlApplicationContext("armin-self-method-overrides.xml"); OriginalDog originalDog = (OriginalDog) context.getBean("originalDog"); originalDog.sayHello("Three-baby"); } }
Console
real execute method Three-baby