常用的@Autowired
这个估计是使用spring最常用的注解了,往一个bean添加依赖,作用应该众所周知
@Value
@Value 一般用作配置类,比如:
@Value("${file.server.host}")
private String basicHost;
AutowiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor 是解析这两个注解的关键
* @see Autowired
* @see Value
*/
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
}
可以看到这个类,继承了InstantiationAwareBeanPostProcessorAdapter实现了父类方法postProcessProperties。并且实现了MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition。这两个bean后置处理器再bean实例化,初始化过程都有有作用的,详情请见 juejin.cn/post/684790…
AutowiredAnnotationBeanPostProcessor实例化做了什么
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
.......省略添加 @Inject 的方法
}
实例化的时候往 autowiredAnnotationTypes 这个set集合放入 Autowired 和value这两个classs。
AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//重要方法,往下走
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
//......校验获取缓存key,省略
//从缓存中获取 InjectionMetadata
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
//重复校验,从缓存取,省略
//重要,往下走就会解析
metadata = buildAutowiringMetadata(clazz);
//将获取到的metadata放到缓存中,让下次的后置处理器来取(postProcessProperties)
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
//对属性的解析 遍历 autowiredAnnotationTypes(初始化的时候塞了三个注解进去)
//看是否这个类的属性有这三个注解,如果有就放到List中缓存下来
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//找属性是否有@Autowired @Value @Inject
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
//判断注解的 require 属性
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
//.....上面是对属性的解析,下面是对方法的解析方法也可以@Autowire等注解
//大概意思差不多就省略,只是两个解析后的结果封装的对象不同
//属性:AutowiredFieldElement 方法:AutowiredMethodElement
//都是继承 InjectionMetadata.InjectedElement
}
while (targetClass != null && targetClass != Object.class);
//将解析完之后的elements(List) 放到 InjectionMetadata对象中,然后缓存到map中
return new InjectionMetadata(clazz, elements);
}
将解析出来之后的数据放到缓存之后,肯定有人取get缓存然后处理,如果了解bean的初始化就知道是哪个类的哪个方法去取这个缓存来解析的
AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
这个方法也在spring的后置处理器中讲过了,主要是往bean中填充属性等等
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//调用上面的findAutowiringMetadata这个方法
//这个方法刚才也看了,一进去就会往缓存中取数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//调用inject,往下看inject做了什么
metadata.inject(bean, beanName, pvs);
}
return pvs;
}
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//............
//循环injectedElements 这个就是刚才解析完放到缓存的List
for (InjectedElement element : elementsToIterate) {
//往下看inject做了什么
element.inject(target, beanName, pvs);
}
}
}
以属性的解析为例
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//获取需要注入的属性
Field field = (Field) this.member;
Object value;
//如果有缓存,就从缓存中拿,这个主要应用在原型模式
//原型模型,每次都要生产bean,每次都要重新注入依赖
//所以如果有缓存,就少了解析的过程
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
//构造依赖的实体类 DependencyDescriptor
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//解决依赖
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
//如果还没有缓存,就把依赖信息缓存下来
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
// 通过 ShortcutDependencyDescriptor 来缓存
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
//反射调用,注入属性值
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
//判断依赖是否 optional 类型
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
//判断依赖是否 是objectFactory 类型
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;
}
}
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
//拿出缓存,如果是原型模式,就会从缓存中获取依赖值
//直接返回
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
Class<?> type = descriptor.getDependencyType();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
//对集合数组的处理,所以,可以注入一个 list 或者 map 等集合数组
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//通过依赖类型去容器中找
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
//如果找到的依赖有多个
if (matchingBeans.size() > 1) {
//通过名称去匹配
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
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 就通过 beanFactory.getBean 去实例化一个bean
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);
}
}
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//通过类型去容器中bean名称
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
//从依赖的缓存中获取
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的calss或者bean对象
//放到resutl
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
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) {
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;
}
过程:
- 1.对于原型模型的对象,会对需要注入的信息做缓存
- 2.DefaultListableBeanFactory#resolveDependency:解决依赖
- 3.DefaultListableBeanFactory#doResolveDependency:真正处理依赖,会判断能不能从缓存中获取依赖,如果可以直接返回。一般只有原型才有缓存,如果缓存没有就开始解析依赖。先通过
resolveMultipleBeans去判断是否是集合数组,如果是,就通过findAutowireCandidates寻找需要依赖的,如果不是集合框架,也是通过findAutowireCandidates寻找依赖,寻找依赖的时候是通过Class类型去找名称,通过名称去找实体类或者是class,找到之后返回去,但是如果找到多个就通过determineAutowireCandidate来判断需要注入那个,主要是通过属性名称跟bean名称来匹配,如果匹配不到合适的就报错,如果找到的时候对象直接注入,如果找到的是class就通过beanFactory.getBean 去容器中实例化bean - 4.所以@Autowired 是通过class 去找bean名称,在通过bean名称去容器中拿,如果拿到多个就通过属性名称去匹配。
总结
AutowiredAnnotationBeanPostProcessor 主要是解决@Autowired 和 @Value注解的关键, AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor继承了InstantiationAwareBeanPostProcessorAdapter这两个,再bean的实例化过程分别先后被调用相应的方法 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 是先调用解析出需要依赖注入的属性,放到缓存中。 InstantiationAwareBeanPostProcessorAdapte#postProcessProperties 后执行,这是后缓存中已经有了需要依赖注入的属性集合,直接拿,然后解析,最终通过bean工厂的getBean方法从spring容器中获取依赖,调用反射注入进去。