概述
上一篇文章中我们解释了Spring对于类级别的注解的解析过程,通过类级别的注解spring基本是将所有该加载的类都加载到待解析的BeanDefineMap中去了。但是BeanDefineMap可不是实例化的bean哦,可以说通过类级别的注解之后Spring还是一个粗糙的商品,但是要变成一个精美的可以使用的Bean还需要将这个粗糙的商品进行一番美化。那么这个美化的动作就是content.getBean()方法了。考虑到类的实例化过程可能会依赖其他的bean还有一些类内部的注解比如@Autowired、@Queries等都需要考虑。所以说getBean是比较复杂的。之前通过源码查看的时候稍微看到了这块,感到压力很大。但是有时候确实让人迫不得已的要去做这件事。因为我们还没有解释@Autowired是如何注入的问题。所以就让我们通过这期的学习解答这个问题吧!
在之前我们说上述代码就是实例化bean的代码。这块我们主要看一下
beanFactory.preInstantiateSingletons();方法
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
//拿到所有注册的bean的名称
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//遍历
for (String beanName : beanNames) {
//拿到粗糙的bean
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断是否为工厂bean
if (isFactoryBean(beanName)) {
//给beanName+前缀 & 符号
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
//如果是工厂bean
final 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());
}
//调用正在的getBean
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//非工厂bean
getBean(beanName);
}
}
}
// 通过上述方法就将bean注册进去了。这里迭代做一些处理
for (String beanName : beanNames) {
//拿到单例bean
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
//判断当前的bean是否实现了SmartInitializingSingleton接口
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
//做一些后置处理
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
通过上边的分析,我们知道getBean是很重要的方法。那么这块做了哪些工作?
我们看到这里的doGetBean方法,说明这里是正真搞事情的地方。毫无疑问,伟大的目标必将付出艰苦的努力。这块的代码很长!
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//先把传入的名称进行转化。因为可能传入的是别名什么的,所以要处理一下,如果之前都添加了前缀
final String beanName = transformedBeanName(name);
Object bean;
// 先尝试从缓存中加载bean,如果不存在会调用getBean方法,因为创建单例bean的时候存在循环依赖的问题
//Spring创建bean的时候是不等bean创建结束就将bean的ObjectFactory提早曝光。就是将ObjectFactory加入到缓存。
//一旦下一个bean创建的时候需要依赖上一个bean的时候则可以直接使用
//从缓存或者singleFactories中的ObjectFactory中获取。
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 + "'");
}
}
/**
* 如果sharedInstance是普通的单例bean,下面的方法会直接返回。但如果
* sharedInstance是FactoryBean类型的,则需调用getObject工厂方法获取真正的
* bean实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回
* 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
*/
//有时候BeanFactory返回的并不是实例本身而是指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//Spring只能解决单例对象的setter注入的循环依赖,不能解决构造器注入,
//也不能解决多实例的循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//如果已经加载的类没有当前类就从parentBeanFactory中加载。
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//若存在父工厂,切当前的bean工厂不存在当前的bean定义,
//那么bean定义是存在于父beanFactory中
//获取原始名称
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
//委托给构造函数
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// 没有args,委托给标准的getBean()处理
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
//使用父工厂创建bean
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
/**
* 方法参数typeCheckOnly ,是用来判断调用getBean(...) 方法时,表示是否为仅仅进行类型检查获取Bean对象
* 如果不是仅仅做类型检查,而是创建Bean对象,则需要调用markBeanAsCreated(String beanName) 方法,进行记录
*/
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//从容器中获取beanName相应的GenericBeanDefinition对象,并将其转换为RootBeanDefinition对象
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查当前创建的bean定义是不是抽象的bean定义
checkMergedBeanDefinition(mbd, beanName, args);
//处理dependsOn的依赖(这个不是我们所谓的循环依赖 而是bean创建前后的依赖)
//依赖bean的名称
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
//beanName是当前正在创建的bean,dep是正在创建的bean的依赖的bean的名称
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//保存的是依赖beanName之间的映射关系:
//依赖beanName -> beanName的集合
registerDependentBean(dep, beanName);
try {
//获取dependsOn的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//是单例则创建单例Bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//这里是重点
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//清除旧信息
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// 如果是一个属性,就创建
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//指定scope上实例化bean
String scopeName = mbd.getScope();
final 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);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
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) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
//一些检测
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
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());
}
}
return (T) bean;
}
通过上述代码查看,我们大概描述一下getBean的过程,首先对bean的名称做一些处理,之前的bean名称都是添加工厂名称的。所以要处理一下。处理完之后先从缓存中获取bean,同时将该bean对应的ObjectFactory加入到缓存中,同时如果从缓存中获取到之后就进行对Bean进行判断,看是否为工厂Bean,如果是工厂bean就需要返回对应方法的返回结果。判断完毕之后就对bean的属性进行初始化了,如果是单例就处理单例,如果是property就相应做处理。当然还有对scope做处理的。我们一般都是单例吧。当然如果没有从工厂中获取到bean的话就尝试从父工厂中获取。
那么我们看一下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<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 验证以及准备覆盖方法
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 给BeanPostProcessors一个机会来替换原来的bean
//该方法里有两个接口可以对bean进行处理
//instantiationAwareBeanPostProcessor
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 {
//如果BeanPostProcessors没有做处理就自己创建
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
//这里才是真正创建bean的地方
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//从缓存中移除
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//这里处理类内注解,通过查看我们发现主要有图所示的处理类。这些类是爱注册beanpostprocessors中加入的
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//处理的过程
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
//是否提前曝光
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
//对bean进行填充
this.populateBean(beanName, mbd, instanceWrapper);
//这块是实例化bean调用后置处理器的部分exposedObject就是bean实体
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
if (earlySingletonExposure) {
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
大概看源码发现doCreateBean才是主要的创建Bean的地方,主要的操作就是对类内部注解进行解析,然后解析完毕之后会统一调initializeBean方法。initalizeBean就开始执行Aware、前置处理器、初始化方法、后置处理器等顺序进行执行,通过这些方法后类才真正的实例化并注册到IOC中。至于initalizeBean没有什么可说的,都是常规操作。但是我们需要记住的是它调用的过程,首先是一波Aware接口的调用,之后是BeanPostProfrosses的前置处理器,然后是Bean的初始化方法,最后是BeanPostProcessors的后置处理方法。而且这个InitalizeBean的方法是只要调用了getBean都会执行。所有保证了InitalizeBean里边的方法都可以执行到到。
最后
以上就是帅气硬币为你收集整理的SpringBoot源码学习(十一) - bean的实例化过程的全部内容,希望文章能够帮你解决SpringBoot源码学习(十一) - bean的实例化过程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复