@Resource注入

tech2026-04-07  2

​​​​​​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

最新回复(0)