「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战」
resolveDependency
- DependencyDescriptor:依赖描述
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
//初始化参数名称发现器
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
//就是1.8中的Optional(方法参数是这个)
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 {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
初始化参数名称获取器
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
//get获取的是这个对象
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
public DefaultParameterNameDiscoverer() {
if (KotlinDetector.isKotlinReflectPresent() && !NativeDetector.inNativeImage()) {
addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
}
//默认的反射获取器
addDiscoverer(new StandardReflectionParameterNameDiscoverer());
//本地变量表
addDiscoverer(new LocalVariableTableParameterNameDiscoverer());
}
在jdk1.7(反射不可以)和1.8(需要配参数)中很难获取参数的变量名称,因此这里需要标准的反射和本地变量表(作为备用)。
正常处理
else {
//注意:这里有个lazy,就是判断属性或方法参数有@Lazy注解,如果有则生成实现懒加载代理对象并返回(使用到的时候才创建);如果没有lazy注解则result=null
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
@Lazy相关
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
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) {
BeanFactory beanFactory = getBeanFactory();
Assert.state(beanFactory instanceof DefaultListableBeanFactory,
"BeanFactory needs to be a DefaultListableBeanFactory");
final DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
TargetSource ts = new TargetSource() {
@Override
public Class<?> getTargetClass() {
return descriptor.getDependencyType();
}
@Override
public boolean isStatic() {
return false;
}
@Override
public Object getTarget() {
Set<String> autowiredBeanNames = (beanName != null ? new LinkedHashSet<>(1) : null);
Object target = dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, 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");
}
if (autowiredBeanNames != null) {
for (String autowiredBeanName : autowiredBeanNames) {
if (dlbf.containsBean(autowiredBeanName)) {
dlbf.registerDependentBean(autowiredBeanName, beanName);
}
}
}
return target;
}
@Override
public void releaseTarget(Object target) {
}
};
ProxyFactory pf = new ProxyFactory();
pf.setTargetSource(ts);
Class<?> dependencyType = descriptor.getDependencyType();
if (dependencyType.isInterface()) {
pf.addInterface(dependencyType);
}
return pf.getProxy(dlbf.getBeanClassLoader());
}
默认实现类是ContextAnnotationAutowireCandidateResolver,在这里会判断是否有lazy注解,如果有就返回一个针对Lazy的代理对象(这里和AOP有关系)。
- 如果是包装的代理对象,那么在调用对象方法的时候,会首先调用getTarget方法获取Bean并调用方法。
doResolveDependency
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
//缓存相关,缓存里的其实是beanName,这里会通过beanname来获取bean实例,在单例中不会走到这里进来
//为什么缓存的是名称?因为如果缓存的对象也是原型,那么也需要创建一个新的缓存类型对象
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
//处理@Value注解
Class<?> type = descriptor.getDependencyType();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
//占位符{}填充,从properties里取
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
//SPEL填充(#{}),这里会从Spring容器中获取bean
value = evaluateBeanDefinitionString(strVal, bd);
}
//类型转换器,将value转化为指定的类型
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
//这里对应的是没有通过@Value的情况
// 这里是处理其他情况的,比如:@Autowired的是某个bean类型的容器(list/map等等,map的key必须是String)
//如果是泛型,就会报错;如果是Object,就会把当前的所有bean都放进来
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//这里是获取bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
//如果获取到空,且是required= true,则抛异常
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
//找到了多个
if (matchingBeans.size() > 1) {
//一一判断,byName就是这里实现的
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
//没找到且require,也抛异常
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
//找到一个:那就赋值这个
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
//找到了一个就直接赋值
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
//class的原因见下面,如果这里是class,那么需要创建对象
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
-
占位符填充是从properties里取的,这个文件被封装到environment里了。
- environment对象中包括properties文件,以及一些其他的变量,包括VMargs,系统变量等。
- 需要在某些地方做@PropertySource()的注解,来指定和关联。
-
Nullbean:@Bean的方法返回的是个null,那么单例池中对应的bean就变成nullBean了。
findAutowireCandidates
根据上面的流程,可以得知这里的结果是很重要的,因此这个方法是这部分的一个核心点。
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//根据bean类型,从本BF以及父BF中,返回所有符合的bean的名字
//这里默认是从所有的bean(不只是单例)中获得bean名称
//会从BF中的BD来获取
//如果是factoryBean,则是通过factoryBean的getClass来判断类名
//如果目前单例池中没有对应的bean对象,那么就从BD中来获取
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
//和Spring启动有关,这个变量的写入在registerResolvableDependency方法
//因此这里也算是一部分内容,获取bean名称+实例(或者class对象)
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
//到这里就找到了所有符合的bean,这里做筛选
for (String candidate : candidateNames) {
//是否是自己,因此如果同个bean类型有多个,那么会先考虑注入别的bean对象,而非先考虑注入自身
//如果不是自己,并且可以用来autowired,就会加到result里
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
//只有到result是空了,才会考虑是否需要对自己进行注入自己的bean
if (result.isEmpty()) {
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
//这里的isAutowireCandidate,指的是@Bean是否指定了autowiredCandidate=true(默认是true),实际上是通过QualifierAnnotationAutowireCandidateResolver处理的,这里是责任链设计模式,包括:autowired的判断,以及根据bean的泛型判断
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
determineAutowireCandidate
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
//判断某个bean有没有primary注解,有就返回那个primary的(这里是根据BD来判断的);但一组bean只能有一个@Primary,在这里会报错
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
//这里说明没有@Primary,那么这里会通过@Priority(int)来决定选哪个(int越小优先级越高),这个注解只能写在类上,不能写在方法上即不能和@Bean+方法的类型组合
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback - 这里根据bean的名称来获取
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
return null;
}
-
这里有一个问题:如果bean有了Primary或者priority的,那么其他优先级不高的可能就不会被用到。
因此,在
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);这一步骤中,如果创建了Object,value就是bean;如果没创建好,这里的value就是class对象。