在启动程序的时候,启动代码如下:
public class SpringMain {
public static void main(String[] args) {
//初始化spring容器 在初始化的时候完成了依赖注入
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTest.class);
}
}
在执行该代码的时候便完成了spring容器的初始化的过程。
而依赖注入的功能便是在spring容器初始化(即初始化bean–该过程是bean的生命周期)的时候完成。
springBean有完整的生命周期。
java对象只是我们new出来的。
springBean可以是java对象,java对象不可以是bean。
程序执行启动类的时候,会调用c++代码启动jvm虚拟机
jvm虚拟机会将编译好的class文件加载到jvm的内存当中,比如说方法区。
当遇到new关键字的时候,会根据方法区的java模版,去堆上分配一块内存用来存储该new的对象
这些类会被编译为class文件
当程序启动的时候,会调用c++启动jvm虚拟机
jvm虚拟机会将class文件加载到虚拟机当中
当虚拟机执行到启动类的部分的时候,即如下部分
spring会先去解析SpringTest.class类中的@ComponentScan注解中包中的所有的bean
获取到所有的bean之后,要分别获取各自bean的类上的各种注解
如@Lazy @DependOn等等,然后spring会new一个对象(BeanDefinition的子类)来存储这些信息
随后,该对象会被放在一个map中
然后调用preinstantiateSingleton方法遍历该map,获取到beanDefinition的对象,通过该对象判断该bean是否是单例,是否有懒加载等等等等,遍历验证完该对象之后,会将该对象放在单例池当中。
单例对象生成过程:
通过javac编译为class文件
spring对class文件进行解析(读取注解)并生成beanDefinition对象存储bean的基本信息
将该beanDefinition存储在map中
调用preinstantiateSingleton获取map,遍历map,对map中的该beanDefinition内存储的信息进行验证,验证是否是单例,是否有懒加载等等注解
将验证后没问题的bean存储到spring的单例池中
spring提供了程序员扩展的空间
在对象存到map中后,调用preinstantiateSingleton方法之前,程序员可以进行一定的扩展。
spring在将数据存放到map中之后,调用preinstantiateSingleton方法之前,会看一下程序员是否进行了扩展,如果进行了扩展,spring就会调用扩展的一些方法将该map传过去。
程序员获取到了map,即获取到了BeanDefinition,在BeanDefinition中有一个是beanClass,存储的就是我们使用@Component等注解的X类。程序员可以修改该beanClass的值,比如将X改为了Y。修改的这一步就是在进行扩展操作。修改完成之后再将值重新放回map中。
此时spring再将map放到spring的单例池中。此时放进去的就是Y而不是X了。
public class IndexService {
public IndexService(){
System.out.println("indexService construct");
}
}
@Component
public class UserService {
public UserService(){
System.out.println("UserService construct");
}
}
@ComponentScan("com.guo.admin.web.spring")
public class SpringTest {
}
//扩展类
@Component
public class BeanDefinationSelf implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("userService");
genericBeanDefinition.setBeanClass(IndexService.class);
}
}
//在该类中获取到添加了@Component注解的UserService类,然后将其的BeanClass值设为了IndexService类。
启动类
public class SpringMain {
public static void main(String[] args) {
//初始化spring容器 在初始化的时候完成了依赖注入
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTest.class);
System.out.println(context.getBean(IndexService.class));
}
}
执行结果如下:可以看到IndexService对象生成了,成为了Spring的bean对象。
如果没有扩展类(将扩展类上的@Component注解注释掉)的话,启动启动类的结果是如下图:
该demo实现了对speing的二次扩展。
public AnnotationConfigApplicationContext(Class... componentClasses) {
this();
this.register(componentClasses);
this.refresh();//真正实现spring 的bean初始化的方法。
}
进入this.refresh();方法中
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//该方法完成了扫描操作--该方法执行完成之后--,an Definition放进了map中
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
//该方法完成bean对象的初始化操作。如果bean类对象的构造方法里面有日志输出,则在此方法执行之后,日志会输出出来。
//即该方法中完成了bean对象的生命周期过程
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
bean对象初始化的方法源码:finishBeanFactoryInitialization();
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
//该方法将会实例化所有非懒加载的单例对象
beanFactory.preInstantiateSingletons();
}
实例化非懒加载的单例对象源码:beanFactory.preInstantiateSingletons();
该方法获取所有的bean的名字,通过循环一个一个getBean
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
//该list是所有bean的名字 然后对该list做了一个循环 根据名字去map中获取到对应的beanDefinition对象
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
//在这里合并
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());//判断该对象是不是
} while(!bd.isSingleton());//判断该对象是不是单例对象
} while(bd.isLazyInit());//判断该对象是不是非懒加载的对象
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
//如果验证结束没有问题(不是懒加载,是单例),则执行getBean方法去完成实例化。
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
//该行代码非常重要 验证bean的名字是否非法
String beanName = this.transformedBeanName(name);
//bean的名字没有非法情况后,下面该行代码会根据名字去单例池中拿bean,看单例池中是否已经存在了被实例化的该bean对象
Object sharedInstance = this.getSingleton(beanName);
Object bean;
//如果发现该bean对象已经在单例池中存在了,则走这个if方法 ---但是我们需要知道,该doGetBean方法就是在刚开始初始化bean的时候去调用的,所以不可能进入这个if方法中。
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
}
//因此,出了if,程序进入了else方法
else {
//该if,是判断该bean对象是否正在创建过程中,如果是,则抛出异常
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
//在该行代码中解析合并后的bd对象
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
//判断bean类对象上是否添加了@DependOn注解
String[] dependsOn = mbd.getDependsOn();
String[] var11;
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
//判断是否是单例对象---如果是单例对象,则进入该if方法 然后执行createBean方法,此时bean才开始实例化了。
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
Scope 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, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
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", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
//校验日志
if (this.logger.isTraceEnabled()) {
this.logger.trace("Creating instance of bean '" + beanName + "'");
}
//将mbd(RootBeanDefinition)赋值给mbdToUse----
RootBeanDefinition mbdToUse = mbd;
//获取mbd的class这个属性的值(值就是bean对象的类的全限定名,这个值就是这个类,获取到了类)
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
//这个方法也是比较重要的一个方法
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}
Object beanInstance;
try {
//第一次调用后置处理器,这里面还是进行验证
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var10) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}
try {
//--------------------------
//该行中的doCreateBean创建bean开始了~~~~ 在该行代码中,完成了原身对象和代理对象的创建(如果只是创建bean则创建bean,如果该bean被aop了,则创建了bean和它的代理bean)
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
//判断是否是单例 如果是单例 则将cache remove 掉
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//实例化对象,里面第二次调用后置处理器 这里实例化的是对象,而不是bean,我们需要注意。当该方法执行完成后,构造方法中如果有日志输出,则会输出,说明对象被实例化出来了,但是这并不表示bean创建出来。因为如果我们debug一下,可以看到该bean里面的一些属性还是没有值的,还是null,只是构造方法执行完成了而已。此时实例化的是对象。
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
//debug到这一行的时候,我们可以看到这个bean中的属性还是没有值的,上一行的
//instanceWrapper = thiscreateBeanInstance(beanName, mbd, args)这个方法只是将对象实例化了,但是bean还没有被实例化。
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//通过后置处理器来合并beanDefinitation 举例:AService中有两个使用@Autowire注解的属性,该方法就是将所有需要注入的属性都合并起来放到一个list集合中
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;
}
}
//判断是否允许循环依赖
//mbd.isSingleton() 默认是单例,所以结果是true
//this.allowCircularReferences 没讲
//this.isSingletonCurrentlyInCreation(beanName) 百分之百是true 理由为:老师还没讲。
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
//如果允许循环依赖的话,则执行if中的方法
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
//第四次调用后置处理器,spring需要将该bean对象提前暴漏出来,并且做aop
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
//将bean对象赋值给 Object exposedObject
Object exposedObject = bean;
try {
//该方法进行属性的填充 就是我们常说的自动注入,里面会完成第五次和第六次的后置处理器的调用
//在该方法中,先判断是否需要进行属性的注入,如果需要,才进行属性的注入工作
this.populateBean(beanName, mbd, instanceWrapper);
//初始化spring,里面会进行第七次 第八次的后置处理器的调用
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);
}
}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} else {
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return this.obtainFromSupplier(instanceSupplier, beanName);
} else if (mbd.getFactoryMethodName() != null) {
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized(mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
//该行用来获取到构造方法后对构造方法进行推断
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
ctors = mbd.getPreferredConstructors();
//如果构造方法不为null的话,就反射autowireConstructor,如果为null 的话,就instantiateBean执行这个方法,获取默认的无参构造方法实例化对象
return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
return this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
}
}
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(() -> {
//通过执行instantiate得到默认的构造方法
return thisx.getInstantiationStrategy().instantiate(mbd, beanName, this);
}, this.getAccessControlContext());
} else {
beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
this.initBeanWrapper(bw);
return bw;
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
}
}
在该方法中通过执行instantiate方法得到默认的构造方法
instantiateClass方法中
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
//ctor.newInstance(args)该方法完成对象的实例化
return KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ? BeanUtils.KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args);
} catch (InstantiationException var3) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", var3);
} catch (IllegalAccessException var4) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", var4);
} catch (IllegalArgumentException var5) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", var5);
} catch (InvocationTargetException var6) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", var6.getTargetException());
}
}
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
//执行或者说回调awre方法(并不是所有的awre方法都在这个方法中进行回调)
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//执行spring的生命周期回调 该方法执行处理的是使用注解的方法
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
//执行生命周期初始化回调方法 这里执行的是接口和xml方法的
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
//下面这一行代码中多后置处理器进行循环,通过其中一个后置处理器处理完成了aop
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Object current;
//获取到所有的后置处理器后进行循环处理
for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
BeanPostProcessor processor = (BeanPostProcessor)var4.next();
current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
}
return result;
}
处理aop的后置处理器如下图,通过该后置处理器改变了bean,变成了代理对象
上图体现了策略模式
所有的后置处理器都实现了BeanPostProcessor,每个方法都有不同的实现。有的没有对bean进行处理,有的则进行了改动。
其中有一个后置处理器的实现是这样的,看下面的代码块
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//得到所有的注解信息 findLifecycleMetadata(找到生命周期的元数据)
//这里使用@PostConstruct注解的bean里面的这个方法(假设叫init())就会被找到,找到后被存储了起来
InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata metadata = this.findLifecycleMetadata(bean.getClass());
try {
//在该行代码中通过反射执行元数据方法即可。如上面的init()方法就会被执行
metadata.invokeInitMethods(bean, beanName);
return bean;
} catch (InvocationTargetException var5) {
throw new BeanCreationException(beanName, "Invocation of init method failed", var5.getTargetException());
} catch (Throwable var6) {
throw new BeanCreationException(beanName, "Failed to invoke init method", var6);
}
}
spring根据bean的首字母进行排序进行创建
比如有x,y这两个bean要创建,那么会先创建x,后创建y
这三种方法可以同时存在
代码就是这个顺序
生命周期回调有两种方法:初始化回调和销毁回调
生命周期的初始化回调方法。
在上面的java代码块中,有一行代码是用来判断spring容器是否允许循环依赖的,即下行代码:
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
即spring在创建bean的过程中,该代码会判断有没有开启spring的循环依赖,判断的结果主要取决于allowCircularReferences这个属性的true false值。
通过看代码,我们可以看到该allowCircularReferences的值默认为true。
public AbstractAutowireCapableBeanFactory() {
this.allowCircularReferences = true;
}
可以修改allowCircularReferences的值为false。
由于源码我们无法更改,只能在主启动类中进行更改
public class SpringMain {
public static void main(String[] args) {
//初始化spring容器 在初始化的时候完成了依赖注入
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTest.class);
//这两行代码是新增用来修改allowCircularReferences值的。但是!不起作用的!原因在下面写着。
AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) context.getBeanFactory();
beanFactory.setAllowCircularReferences(false);
System.out.println(context.getBean(IndexService.class));
}
}
在
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTest.class);
之后对allowCircularReferences进行赋值为false。
但是我们需要注意的是,在
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTest.class);
执行完成之后,bean对象已经初始化完成,bean的属性也均赋值完成,因此在该行代码之后对allowCircularReferences进行重新赋值是无用的,因为bean已经初始化完成。
解决方案
public class SpringMain {
public static void main(String[] args) {
//这里我们使用无参构造方法创建了context
//然后再执行context的register方法,然后添加我们修改属性值的方法,最后执行refresh方法。
//这样就实现了属性修改。为什么这样能实现属性修改呢?看下面文字讲解。
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(SpringTest.class);
AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) context.getBeanFactory();
beanFactory.setAllowCircularReferences(false);
context.refresh();
System.out.println(context.getBean(IndexService.class));
}
}
当代码为
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringTest.class);
的时候,我们创建context是使用了有参构造,而有参构造的源码为:
public AnnotationConfigApplicationContext(Class... componentClasses) {
this();//调用默认构造方法
this.register(componentClasses);
this.refresh();
}
而我们的解决方案中的代码为:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
使用的是无参构造创建的context,无参构造的源码为:
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
这个无参构造方法就是 有参构造方法中的 this()方法。
因此方案一中,
先调用无参构造,再执行register方法,然后执行手动代码(修改属性),最后执行refresh方法,便可以成功修改属性。因为refresh方法才是正式初始化bean的方法。
populateBean()方法源码 该方法实现bean的属性注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var5 = this.getBeanPostProcessors().iterator();
while(var5.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var5.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (continueWithPropertyPopulation) {
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (mbd.getResolvedAutowireMode() == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowireMode() == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//获取所有的后置处理器 转换为迭代器进行循环处理
Iterator var9 = this.getBeanPostProcessors().iterator();
//在这里进行后置处理器的循环
//也就是说,每个后置处理器依次对该bean进行处理,完成该bean的属性注入操作
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
//该行执行完成之后,bean的属性才被注入进去的。这里插入一个问题,看下面文字。
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
}
首先,在上面代码块中
Iterator var9 = this.getBeanPostProcessors().iterator();该代码获取到了所有的后置处理器,并转换为了迭代器。
即, this.getBeanPostProcessors()获取到的是一个后置处理器x,y,z等的list集合。当循环到了AutowiredAnnotationBeanPostProcessor这个后置处理器的时候,再执行
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)这个方法之后,bean对象中如果有使用@Autwired注解注入的属性X,那么在这一行代码执行完成之后,该属性就有值了。
说的再直白一点便是:
如果该X的构造方法中有日志输出,那么在这一行代码执行完成之后,该日志便会输出来。说明该X对象被创建了。但是我们需要注意的是,是X对象被new出来了,而不是被初始化完成了。
如果属性是使用@Resouce这个注解去注入的话,会被@CommonAnnotationBeanPostProcessor注解解析并完成该属性的值的注入。
此时,X被new出来之后,X便要继续走初始化生命周期的流程了。同理,走到这儿的时候,X里面如果有需要注入的属性M,则一样要走M的声明流程。这里就有一个情况,X中有Y属性,Y中有X属性。这种情况怎么走呢?
代码如下:
@Component
public class UserService {
@Autowired
private IndexService indexService;
public UserService() {
System.out.println("UserService construct");
}
}
@Component
public class IndexService {
@Autowired
private UserService userService;
public IndexService() {
System.out.println("indexService construct");
}
}
当程序主启动类启动的时候,会初始化扫描包下面的所有的component。
如果首先初始化的是IndexService,那么执行到populateBean()方法时,需要给IndexService的属性进行值注入。此时IndexService的属性是UserService。
看上图,走到这一步的时候,ibp是AutowiredAnnotation···的后置处理器,(UserService在IndexService里面就是用@Autowired注解去实现注入的),debug的那一行还没有执行的时候,userService的值还是空的,值还没有注入进来。
当执行了这一步的时候,我们可以看到下图,直接跳到了getBean方法,开始getBean(userService)了。
然后也是一模一样的流程,走到下图这一步的时候,userService对象被创建出来了。(执行了构造方法)
然后继续执行,执行到了同样的需要属性注入的地方
该行执行完成之后,马上就跳转到了getBean方法去获取indexService(请看下图)
然后我们可以看到,在doGetBean方法中的第二行方法(下图),indexService的this.getSingleton方法是有值的。
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
//如果下行判断成立,则会走进if代码里面。里面代码是会去第三个缓存中去获取bean对象
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
看这个源码第一行,通过beanName去singletonObjects中找数据。而这个singletonObjects是去单例池中找数据的。如果IndexService还没有初始化完成,并且也不在创建当中,那么返回的值就是一个null,进不了if代码中,该方法便会返回一个null。
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
判断bean是否正在创建中,是通过上块代码块执行的。那么这个
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));
那么,这个Set是哪儿给赋值的呢?
就是在doGetBean方法中
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized(this.singletonObjects) {
//根据beanName没有获取到数据,就进入下面的if里面
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 (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//这一步是在创建单例对象之前执行的一个方法。
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if (recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();
while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
if (newSingleton) {
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
this.beforeSingletonCreation(beanName);源码:该方法就是将beanName放到 Set中去,就表示这个bean正在被创建。
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) &&
//这个方法将bean放到set中,表示该bean正在创建当中。
!this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
然后在this.beforeSingletonCreation(beanName)这一行代码之后的singletonObject = singletonFactory.getObject();,其实执行的就是
return this.createBean(beanName, mbd, args);
这个方法。
在刚进入doGetBean()方法中的时候,会先执行以下方法判断该bean是否已经存在了
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存中查找 该singletonObjects就是一级缓存
Object singletonObject = this.singletonObjects.get(beanName);
//如果是第一次创建bean对象且正在创建过程中,此时singletonObject为null,但是后面的条件为true,此时进入了if方法中
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
synchronized(this.singletonObjects) {
//earlySingletonObjects 是第三个map。该map是三级缓存。在三级缓存中没有找到该bean,取出来的值是null
singletonObject = this.earlySingletonObjects.get(beanName);
//allowEarlyReference该值是在调用getSingleton()这个方法的时候写死传进来的,写死为true,因此该if条件满足,进入了if里面的方法
if (singletonObject == null && allowEarlyReference) {
//singletonFactories 是第二个map
//从该map中再次获取一次beanFactory,此时是能够获取到的。
//是在哪里往singletonFactories里面放数据的呢?在doCreateBean方法里面放的,可以看下面的图。
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//从该工厂中获取到bean
singletonObject = singletonFactory.getObject();
//将bean放到三级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
//将bean从二级缓存中移除,为什么要移除呢?
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
singletonFactories 也是一个map
doCreateBean()方法中
满足是单例,允许循环依赖,当前bean正在创建中这三个条件,便执行addSingletonFactory方法,将bean放在该factory中
一共有三个map
1.singletonObjects 单例池 (可以理解为spring容器)(一级缓存)(存储的是bean对象)
2.singletonFactory 工厂(二级缓存,存放的是工厂)
3.earlySingletonObjects 三级缓存(存储的是对象)
答:防止工厂重复生产对象
singletonObject = singletonFactory.getObject();
该getObejct()方法,具体是走下面这个代码
getEarlyBeanReference()方法如下:
获取到了所有的后置处理器,并进行了循环处理,这样才在工厂中将该bean创建了出来
因此我们每次从二级缓存中执行getObject方法,都是在工厂中创建一次bean对象的过程。为了防止bean对象重复创建(有的bean创建的时间很长,如果重复创建,会影响性能),就出现了三级缓存,我们第一次从二级缓存中创建了对象后,便将其放接了三级缓存中,然后remove了二级缓存。
有三个service:aService,bService,cService,aService和bService中都注入了cService,如果没有三级缓存的话,aService这个bean创建的时候,需要注入cService,工厂创建了一次cService;bService这个bean创建的时候,需要注入cService,工厂又创建了一次cService,那么这样是不太合理的。
1.spring启动,先进行indexService的bean的创建
2.执行到doCreateBean-createBeanInstance执行了indexService的构造方法, indexService的对象创建完成
3.接下来将该indexService放到二级缓存工厂中
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);
});
}
4.接下来执行this.populateBean(beanName, mbd, instanceWrapper)方法进行属性的注入,这里的属性指userService。
5.userService同样先进行对象的创建,然后放到二级缓存工厂中,然后进行属性的注入,此时需要注入的属性是indexService
6.在执行populateBean方法的时候,会跳到getBean方法去获取indexService
7.doGetBean方法中会执行getSingleton方法获取indexService
8.getSingleton方法中,先去单例池中获取bean对象,没有获取到(因为此时indexService还只是对象,而不是bean),接下来去三级缓存中获取,也没有获取到(因为还没有往三级缓存中put过)。最后到二级缓存factory中生产对象,执行getObject方法,在该方法中对后置处理器进行了循环,将indexService创建了出来(在此过程中,也完成了indexService 的PostConstruct方法,完成了aop代理)。
9.userService继续执行initializeBean完成初始化
10.将userService放入单例池中
11.将indexService继续执行initializeBean完成初始化
12.将indexService放入单例池中
放了工厂后,该工厂后期需要对要注入的还不是bean的对象进行改造优化升级,最后改造成bean的。
第一个map:单例池,因为spring的单例对象只会被实例化一次,所以需要一个单例池来缓存该信息
第二个map:缓存的是工厂,主要是为了解决循环依赖。X中注入Y,Y中注入X,先创建X,接下来注入Y的时候去创建Y,在注入Y的属性X的时候,获取到了第二个缓存map中的X对应的工厂,通过工厂对X进行了加工,这里的加工指对X进行代理操作以及其他等等操作,最后将X赋值给Y的属性。
spring容器并不是简单的单例池。
在spring中有很多的组件如beanFactory,三个map,各类后置处理器等所有组件的组成叫做spring容器。
如果我们扩展这个后置处理器,如下行代码那样写
@Component
public class XXX implements InstantiationAwareBeanPostProcessor {
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
}
项目中的所有的bean各自的属性都无法注入了
spring容器启动
随后进行扫描,将类变成bean definition存储到bean defitionMap当中
然后对该map进行遍历,目的是验证是否单例、是否原型、是否懒加载、是否有DepensOn、是否抽象、是否factoryBean、是否这个bean的名字符合等等
随后获取当前实例化的类是否存在单例池当中(是否被创建,如果没有被创建,则去二级缓存中判断是否存在,即判断是否被提前暴漏),是否被提前暴漏,如果没有提前暴漏的话,则spring的bean就会开始创建该bean
创建bean的过程:
通过推断构造方法的过程把当前bean所代表的类当中的构造方法得到一个最佳的构造方法(因为bean代表的是一个JAVA类,一个JAVA类当中可能存在十几个构造方法,不同的注重模型会使用不同的构造方法,因此spring需要推断一下创建该bean的时候需要使用哪个构造方法)
通过反射实例化java对象
根据该java对象对这个bean进行一些初始化的工作,如是否要对该bean进行beanDefinition的合并;如spring容器是否支持循环依赖,如果支持循环依赖的话,需要提前暴漏当前java对象也就是半成品所对应的一个ObjectFactory的工厂类,即提前暴漏该工厂类。
提前暴漏具体指什么?
将要暴漏的对象存储到一个map中,这个map我们称之为是二级缓存。
暴漏执行完成之后,spring会进行属性填充操作,即自动注入。具体指,如A中依赖了B,则将Bset到A中。
set操作执行完成之后,spring会继续执行一些接口的回调操作
然后会进行一个生命周期初始化的回调操作,如添加了注解@PostConstract 或者@InitializerBean等等
如果项目当中有AOP的话,会生成代理,如果没有的话,则不会生成代理。随后会进行事件的发布操作。
bean的声明周期到此完成,该bean对象会被存储到单例池当中。
spring实例化A的时候,会对A进行基本的验证操作,随后查看A是否被提前暴漏,即A对应的ObjectFactory是否有被提前暴漏
此时是没有被提前暴漏的
随后spring会推断出一个合适的构造方法将A实例化出来。
随后A走到了是否要提前暴漏的方法中,因为当前默认容器是都需要提前暴漏的
A被提前暴漏,此时暴漏的是A生成的创建出来的一个ObjectFactory对象,一个工厂对象
随后进行A的属性填充,填充Y
此时发现Y并没有存在spring的容器中,即Y并没有被实例化,此时会进行Y的实例化操作,即进行Y 的生命周期的一系列过程。
在对Y进行属性填充的时候,填充X,发现X并没有被实例化完全(因为此时X实例化流程完成了一半还没有全部完成),会走一遍创建X的流程,在进行创建X的过程中,会发现X已经被提前暴漏了,所以Y能够拿到已经被提前暴漏的ObjectFactory所产生的一个X对象,这样就完成了循环依赖。
注意:此时的spring是单例的,也就是说循环依赖是支持单例的。但是这里需要注意,此时的循环依赖支持的bean对象 A B,不是通过构造函数的方式注入对象的。因为如果AB对象是通过构造方法创建方式的话,那么永远也无法创建该对象出来。
为什么不直接缓存一个X而是缓存一个ObejctFactory呢?
如果缓存的是X,那么从缓存中拿出来的便仅仅是一个X,程序员很难对其进行扩展改变。
但是如果缓存的是ObjectFactory,springFarmwork的内部通过BeanProcessor 这个接口可以对该factory产生X的过程中进行一定的扩展改变干预的,可以得到自己想要的一个Bean对象。
总结:
bean是由一个BeanDefinition来构建的,BeanDefinition可以理解为springBean的一个建模。
b站:https://www.bilibili.com/video/BV1uE411d7L5?p=7&spm_id_from=pageDriver