CommonAnnotationBeanPostProcessor
protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
if (StringUtils.hasLength(element.mappedName)) { //优先处理mappedName
return this.jndiFactory.getBean(element.mappedName, element.lookupType);
}
if (this.alwaysUseJndiLookup) { // alwaysUseJndiLookup=true 根据name查找
return this.jndiFactory.getBean(element.name, element.lookupType);
}
if (this.resourceFactory == null) {
throw new NoSuchBeanDefinitionException(element.lookupType,
"No resource factory configured - specify the 'resourceFactory' property");
}
return autowireResource(this.resourceFactory, element, requestingBeanName); //@Resource的name 未指定名称:这里会先根据名称匹配,然后根据类型匹配 指定名称:则根据名称匹配
}
protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
Object resource;
Set<String> autowiredBeanNames;
String name = element.name; //fieldName、methodName或resource指定名称
if (factory instanceof AutowireCapableBeanFactory) { // 一般都是走这条路的
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
DependencyDescriptor descriptor = element.getDependencyDescriptor();
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) { // bean的名称是否存在
autowiredBeanNames = new LinkedHashSet<>(); // 这条路不存在
resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
}
else { // 根据name查找bean
resource = beanFactory.resolveBeanByName(name, descriptor); // 根据名称查找bean 这里的name不一定能找到bean的,找不到bean,会报BeanCreationException
autowiredBeanNames = Collections.singleton(name);
}
}
else {
resource = factory.getBean(name, element.lookupType);
autowiredBeanNames = Collections.singleton(name);
}
if (factory instanceof ConfigurableBeanFactory) {
ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
for (String autowiredBeanName : autowiredBeanNames) {
if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
}
}
}
return resource;
}
ResourceElement
private class ResourceElement extends LookupElement {
private final boolean lazyLookup;
public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
super(member, pd);
Resource resource = ae.getAnnotation(Resource.class);
String resourceName = resource.name(); // @Resource的name
Class<?> resourceType = resource.type(); // 如果是field,则是field的类型
this.isDefaultName = !StringUtils.hasLength(resourceName); //如果name未指定,则isDefaultName=true
if (this.isDefaultName) {
resourceName = this.member.getName(); // 未指定,则取fieldName或者MethodName
if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
resourceName = Introspector.decapitalize(resourceName.substring(3)); // 去掉set后,首字母变小写
}
}
else if (embeddedValueResolver != null) {
resourceName = embeddedValueResolver.resolveStringValue(resourceName);
}
if (Object.class != resourceType) {
checkResourceType(resourceType);
}
else {
// No resource type specified... check field/method.
resourceType = getResourceType();
}
this.name = (resourceName != null ? resourceName : "");
this.lookupType = resourceType;
String lookupValue = resource.lookup();
this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
Lazy lazy = ae.getAnnotation(Lazy.class);
this.lazyLookup = (lazy != null && lazy.value());
}
@Override
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
getResource(this, requestingBeanName));
}
}
InjectionMetadata
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs); // 注入
}
}
}
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
if (this.isField) { // 字段
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
else { // 函数
if (checkPropertySkipping(pvs)) {
return;
}
try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
CommonAnnotationBeanPostProcessor
public boolean containsBean(String name) {
String beanName = this.transformedBeanName(name);
if (!this.containsSingleton(beanName) && !this.containsBeanDefinition(beanName)) {
BeanFactory parentBeanFactory = this.getParentBeanFactory();
return parentBeanFactory != null && parentBeanFactory.containsBean(this.originalBeanName(name));
} else {
return !BeanFactoryUtils.isFactoryDereference(name) || this.isFactoryBean(name);
}
}
总结:
目前所有场景都没研究到
如果@Resource的name属性,没指定
默认name的值是fieldName或者methodName,如果containsBean返回false,则根据类型匹配
如果containsBean返回true,则根据名称匹配
如果指定了@Resource的name属性
这里是根据名称匹配,如果找不到bean会报BeanCreationException