Spring bean的实例化源码解析(二)------ 循环依赖详解
程序员文章站
2022-05-21 19:26:14
...
文章目录
单例循环依赖
我们先看一个基本的单例bean循坏依赖的现象
@Component
@ToString
@Data
public class LS {
private String name = "LiSi";
@Autowired
ZS zs;
}
@Component
@ToString
@Data
public class ZS {
private String name = "ZhangSan";
@Autowired
LS ls;
}
LS实例化的时候需要依赖注入ZS,则会调用ZS的实例化代码,但是ZS实例化的时候,又要去依赖注入LS,再去调用LS的实例化代码。这样不就无限循环了吗?循环依赖(DefaultListableBeanFactory的allowBeanDefinitionOverriding初始赋值为true)默认是允许的,我们来看Spring如何解决该问题的。
有了前面单例bean实例化源码的基础,我们直接看到AbstractBeanFactory类doGetBean方法获取单例bean的代码。假设现在LS开始实例化。
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//使用调用的方法替代Object sharedInstance = getSingleton(beanName);
//1.LS第一次进来,这里取不到,触发LS实例化
//8.LS依赖注入了ZS,ZS第一次进来,这里取不到,触发ZS实例化
//15.ZS依赖注入了LS,LS第二次进来,singletonObjects取不到
Object singletonObject = this.singletonObjects.get(beanName);
//16.(LS)isSingletonCurrentlyInCreation为true,LS在singletonsCurrentlyInCreation集合中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//17.(LS)earlySingletonObjects取不到
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//18.(LS)singletonFactories可以拿到
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//19.(LS)调用到getEarlyBeanReference获取到LS的实例(可能是LS的代理对象)(LS的zs属性依然是空的),并且放入earlySingletonObjects中,从singletonFactories移除
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
Object sharedInstance = singletonObject
//20.sharedInstance为LS的实例
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 + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//省略部分源码
// Create bean instance.
if (mbd.isSingleton()) {
//2.LS实例化
//9.ZS实例化
sharedInstance = getSingleton(beanName, () -> {
try {
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.
destroySingleton(beanName);
throw ex;
}
});
//暂时认为这里返回了我们实例化的的bean,等讲到FactoryBean接口的时候再来详细看这个方法
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
//省略部分源码
//21.返回LS的实例
return (T) bean;
}
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 + "'");
}
//3.向singletonsCurrentlyInCreation容器中添加了beanName(LS)
//10.向singletonsCurrentlyInCreation容器中添加了beanName(ZS)
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//4.调用createBean获取到的实例化对象(LS)
//11.调用createBean获取到的实例化对象(ZS)
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;
}
//25.ZS从singletonsCurrentlyInCreation移除出去
//33.LS从singletonsCurrentlyInCreation移除出去
afterSingletonCreation(beanName);
}
if (newSingleton) {
//用实际调用的方法代替addSingleton(beanName, singletonObject);
synchronized (this.singletonObjects) {
//26.ZS放入singletonObjects中,从singletonFactories,earlySingletonObjects中移除ZS
//34.LS放入singletonObjects中,从singletonFactories,earlySingletonObjects中移除LS
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
//27.返回ZS的实例
//35.返回LS的实例
return singletonObject;
}
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//5.调用LS的无参构造方法,返回了LS的实例
//12.调用ZS的无参构造方法,返回了ZS的实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//省略部分源码
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//如果是单例且allowCircularReferences(运行循环依赖)默认为true
//isSingletonCurrentlyInCreation(判断singletonsCurrentlyInCreation中是否含有该beanName,显然是含有的)
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//6.LS放入singletonFactories中
//13.ZS放入singletonFactories中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//7.LS去依赖注入ZS,触发ZS实例化的代码
//14.ZS去依赖注入LS,触发LS实例化的代码
//22.ZS完成了LS的依赖注入
//28.LS拿到ZS的实例,完成了LS依赖注入
populateBean(beanName, mbd, instanceWrapper);
//这里可能会返回实例的代理对象(AbstractAutoProxyCreator的postProcessAfterInitialization方法)讲到aop的时候再看代理对象的生成
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
//23.(ZS)这里第二个参数为false,不从singletonFactory再次获取ZS的实例,earlySingletonReference 为空
//29.(LS)从earlySingletonObjects中拿到LS的实例(可能是LS的代理对象)
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
//30.(LS)(如果LS能生成代理对象)由于LS被ZS循环依赖注入进来,导致提前生成代理对象,exposedObject是LS本身,不是代理对象,bean也是LS的本身
if (exposedObject == bean) {
//31.(LS)exposedObject赋值为earlySingletonReference
//(如果LS能生成代理对象)由于getEarlyBeanReference可能拿到的是LS的代理对象(LS生成了代理对象,则earlyProxyReferences的Map记录了LS),导致initializeBean方法不会再返回LS的代理对象(AbstractAutoProxyCreator的postProcessAfterInitialization方法发现earlyProxyReferences中有LS,直接返回LS,不会重复生成LS的代理对象)
//这里需要把ZS依赖注入LS触发LS的getEarlyBeanReference生成的LS实例earlySingletonReference赋值给exposedObject返回
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
//24.返回ZS的实例(可能是代理对象)
//32.返回LS的实例(可能是代理对象)
return exposedObject;
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
//向singletonFactories容器中添加了的beanName和
//() -> getEarlyBeanReference(beanName, mbd, bean)
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
//这里有可能会返回代理对象(咋生成的,我们到aop再来说明,可以看AbstractAutoProxyCreator的getEarlyBeanReference方法)
//目前的代码ZS LS都不会生成代理对象
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
到此单例的循环依赖就结束了。
单例构造函数循环依赖
再来看单例基于构造函数的循环依赖的情况。
@Component
@Data
@ToString
public class ZS {
private String name = "ZhangSan";
public ZS(LS ls){
}
}
@Component
@Data
@ToString
public class LS {
private String name = "LiSi";
public LS(ZS zs){
}
}
实际上这种方式启动直接会报错,我们来看看为什么。
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 + "'");
}
//1.向singletonsCurrentlyInCreation容器中添加了beanName(LS)
//4.向singletonsCurrentlyInCreation容器中添加了beanName(ZS)
//7.再次向singletonsCurrentlyInCreation容器中添加beanName(LS)
//使用调用的代码代替beforeSingletonCreation(beanName);
//singletonsCurrentlyInCreation为Set容器
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
//8.!this.singletonsCurrentlyInCreation.add(beanName)为true,直接抛出异常。
throw new BeanCurrentlyInCreationException(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);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//2.LS通过构造函数实例化
//5.LS通过构造函数实例化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//部分源码
}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//省略部分源码
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//3.LS构造函数需要传入ZS的实例,触发ZS实例化
//6.ZS构造函数需要传入LS的实例,触发LS实例化
return autowireConstructor(beanName, mbd, ctors, args);
}
//省略部分源码
}
看懂了上面这里就很简单了,区别于field依赖注入,field依赖注入实际上bean的无参构造函数已经调用完成了,bean的实例已经有了,只是里面的属性还没有值,但是可以使用没有属性的bean去完成依赖注入,然后再去填充bean实例。
那么基于构造函数的循环依赖,没有办法完成吗?其实是可以的。我们可以借助@Lazy去完成。在ZS或者LS的构造函数上加上@Lazy注解就可以了。比如在LS的构造函数上加上@Lazy注解,ZS不变。假设LS先实例化,调用到LS构造函数的时候,不会去触发ZS的实例化(也就没有循环依赖的问题了)!!!而是拿到了ZS的代理对象,当使用ZS的代理对象去调用方法时,代理方法会去beanFactory中拿ZS的实例,再去用ZS的实例去调用方法。
@Component
@Data
@ToString
public class LS {
private String name = "LiSi";
private ZS zs;
@Lazy
public LS(ZS zs){
//这里是ZS的代理对象
this.zs = zs
}
}
@Component
@Data
@ToString
public class ZS {
private String name = "ZhangSan";
public ZS(LS ls){
}
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//LS构造函数实例化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//省略部分代码
}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//省略部分代码
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//看这里
return autowireConstructor(beanName, mbd, ctors, args);
}
//省略部分代码
}
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
//省略部分代码
if (constructorToUse == null || argsToUse == null) {
for (Constructor<?> candidate : candidates) {
int parameterCount = candidate.getParameterCount();
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
try {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
//看这里,返回构造函数依赖注入的参数bean
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
}
}
//省略部分代码
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
Class<?> paramType = paramTypes[paramIndex];
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// Try to find matching constructor argument value, either indexed or generic.
ConstructorArgumentValues.ValueHolder valueHolder = null;
if (resolvedValues != null) {
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// If we couldn't find a direct match and are not supposed to autowire,
// let's try the next generic, untyped argument value as fallback:
// it could match after type conversion (for example, String -> int).
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
if (valueHolder != null) {
//省略部分代码
}
else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
try {
//接着看,处理参数的依赖注入
Object autowiredArgument = resolveAutowiredArgument(
methodParam, beanName, autowiredBeanNames, converter, fallback);
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = autowiredArgumentMarker;
args.resolveNecessary = true;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
//省略部分代码
return args;
}
protected Object resolveAutowiredArgument(MethodParameter param, String beanName,
@Nullable Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) {
Class<?> paramType = param.getParameterType();
if (InjectionPoint.class.isAssignableFrom(paramType)) {
InjectionPoint injectionPoint = currentInjectionPoint.get();
if (injectionPoint == null) {
throw new IllegalStateException("No current InjectionPoint available for " + param);
}
return injectionPoint;
}
try {
//看这里
return this.beanFactory.resolveDependency(
new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
}
catch (NoUniqueBeanDefinitionException ex) {
throw ex;
}
catch (NoSuchBeanDefinitionException ex) {
if (fallback) {
// Single constructor or factory method -> let's return an empty array/collection
// for e.g. a vararg or a non-null List/Set/Map parameter.
if (paramType.isArray()) {
return Array.newInstance(paramType.getComponentType(), 0);
}
else if (CollectionFactory.isApproximableCollectionType(paramType)) {
return CollectionFactory.createCollection(paramType, 0);
}
else if (CollectionFactory.isApproximableMapType(paramType)) {
return CollectionFactory.createMap(paramType, 0);
}
}
throw ex;
}
}
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
//getLazyResolutionProxyIfNecessary处理懒加载的依赖注入的bean
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
//没有懒加载则返回为null
if (result == null) {
//没有懒加载的依赖注入的bean直接去beanFactory中获取
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);
}
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) {
Assert.state(getBeanFactory() instanceof DefaultListableBeanFactory,
"BeanFactory needs to be a DefaultListableBeanFactory");
final DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) getBeanFactory();
//对目标对象的封装
TargetSource ts = new TargetSource() {
@Override
public Class<?> getTargetClass() {
return descriptor.getDependencyType();
}
@Override
public boolean isStatic() {
return false;
}
@Override
public Object getTarget() {
//从beanFactory获取ZS的实例
Object target = beanFactory.doResolveDependency(descriptor, beanName, null, null);
if (target == null) {
Class<?> type = getTargetClass();
if (Map.class == type) {
return Collections.emptyMap();
}
else if (List.class == type) {
return Collections.emptyList();
}
else if (Set.class == type || Collection.class == type) {
return Collections.emptySet();
}
throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(),
"Optional dependency not present for lazy injection point");
}
return target;
}
@Override
public void releaseTarget(Object target) {
}
};
//关于ProxyFactory 和 TargetSource 我们讲到Aop再详细说明(以jdk动态代理为例,想知道TargetSource怎么使用的可以看到JdkDynamicAopProxy和ProxyFactory的父类AdvisedSupport)
ProxyFactory pf = new ProxyFactory();
pf.setTargetSource(ts);
Class<?> dependencyType = descriptor.getDependencyType();
if (dependencyType.isInterface()) {
pf.addInterface(dependencyType);
}
//返回ZS的代理对象,持有了TargetSource可以从容器中获取ZS的实例。
//直到使用LS持有的ZS的代理对象去调用方法才会去beanFactory获取ZS的实例
return pf.getProxy(beanFactory.getBeanClassLoader());
}
彩蛋:
@Component
@Data
@ToString
public class LS {
private String name = "LiSi";
private ZS zs;
@Lazy
public LS(ZS zs){
//这里是ZS的代理对象
this.zs = zs
//如果这里直接使用了zs的代理对象调用方法(去beanFactory获取ZS的实例,zs还没有实例化的情况下,则触发ZS的实例化),则启动会报错。这就和构造函数循环依赖是一样的问题了。
zs.a();
}
}
@Component
@Data
@ToString
public class ZS {
private String name = "ZhangSan";
public ZS(LS ls){
}
public void a(){
}
}