关联博文
Spring后置处理器中的InstantiationAwareBeanPostProcessor详解
Spring中Bean实例化过程中的initializeBean方法
Spring中Bean实例化过程中的populateBean方法
Spring中@Autowired与@Resource自动注入实现原理
Spring中如何获取到一个Bean实例?
从autowiring使用上可以知道,这个autowiring属性在对Bean属性进行依赖注入时起作用。而这是在populateBean中实现的。也就是说,对属性autowiring的处理是populateBean的一部分。在前面我们分析Spring中Bean实例化过程中的populateBean方法可以看到自动注入的解析出现在两个部分。第一部分:
// AbstractAutowireCapableBeanFactory#populateBean int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; }
第二部分:
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
在第一部分为解析自动注入标识resolvedAutowireMode,默认值为AutowireCapableBeanFactory.AUTOWIRE_NO也就是0。当其为0时,不会执行autowireByName或者autowireByType逻辑。
postProcessProperties则可以理解为一种补偿机制,比如AutowiredAnnotationBeanPostProcessor的该方法,会尝试解析@Autowired注解触发依赖Bean的获取过程。
接下来我们从源码角度分析这两部分的流程。
【1】autowireByName和autowireByType
① autowireByName
当resolvedAutowireMode为1时,即AUTOWIRE_BY_NAME
将会触发autowireByName(beanName, mbd, bw, newPvs);
。
方法源码如下:
//AbstractAutowireCapableBeanFactory#autowireByName protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 获取未满足的非简单类型的属性名称 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { // 如果当前容器包含该属性名称对应的bean if (containsBean(propertyName)) { // 触发Bean的获取 Object bean = getBean(propertyName); //更新pvs pvs.add(propertyName, bean); // 注册记录beanName与依赖 bean名称 registerDependentBean(propertyName, beanName); if (logger.isTraceEnabled()) { logger.trace("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else { if (logger.isTraceEnabled()) { logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found"); } } } }
方法如上所示,获取需要解析的依赖bean。遍历循环尝试从容器中获取bean,然后更新到pvs中。最后调用registerDependentBean方法进行beanName与依赖bean名称留存记录。
② registerDependentBean
registerDependentBean
方法如下所示,其使用dependentBeanMap
与dependenciesForBeanMap
记录了beanName都被依赖了哪些bean和dependentBeanName都依赖了哪些bean。
public void registerDependentBean(String beanName, String dependentBeanName) { String canonicalName = canonicalName(beanName); synchronized (this.dependentBeanMap) { Set<String> dependentBeans = this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); if (!dependentBeans.add(dependentBeanName)) { return; } } synchronized (this.dependenciesForBeanMap) { Set<String> dependenciesForBean = this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8)); dependenciesForBean.add(canonicalName); } }
在DefaultSingletonBeanRegistry中维护了一系列final map。其中dependentBeanMap 表示 beanName---哪些bean依赖了beanName,dependenciesForBeanMap 表示 beanName---beanName依赖了哪些bean。
/** Map between dependent bean names: bean name to Set of dependent bean names. */ private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64); /** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */ private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
③ autowireByType
// AbstractAutowireCapableBeanFactory#autowireByType protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4); // 获取未满足的非简单类型的bean名称/属性名称, //如创建我们的XXXMapper时会解析sqlSessionFactory、sqlSessionTemplate String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); // 遍历循环解析 for (String propertyName : propertyNames) { try { // 获取属性描述符 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. // 如果属性类型是Object,直接抛出异常 if (Object.class != pd.getPropertyType()) { // 获取写方法参数对象,就是setXXXXX方法的参数对象 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. // 判断是否为PriorityOrdered对象,即可以忽略order排序规则 // 如果是PriorityOrdered则eager为false,否则为true。 boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 核心方法,解析依赖 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); // 如果解析到依赖对象,比如sqlSessionFactory,那么放到pvs中 if (autowiredArgument != null) { pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { //该方法前面提到过,注册记录bean与依赖bean的关系 registerDependentBean(autowiredBeanName, beanName); if (logger.isTraceEnabled()) { logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
PropertyDescriptor 属性描述符。其包括属性名称、读方法、写方法、属性类型等。
MethodParameter,方法参数类型。其包括方法调用类、所属类、参数类型、参数个数、方法名称、方法返回类型、参数注解、异常类型等等。
如上代码所示,这里会解析得到propertyNames然后遍历解析依赖,之后会同autowireByName一样调用registerDependentBean方法注册记录bean与依赖bean的关系。
那么如何解析依赖呢?我们继续往下看。
④ 依赖解析resolveDependency
继续分析autowireByType,这部分我们分析依赖如何解析的。如下是DefaultListableBeanFactory的resolveDependency方法,这也是依赖解析的核心方法。在下文AutowiredAnnotationBeanPostProcessor的inject同样流转到了该方法。
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { // 默认是DefaultParameterNameDiscoverer,在分析springmvc流程中我们也提到过 descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); // 判断依赖类型,通常这里是parameterType 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 { // 这里是核心入口,这里是ContextAnnotationAutowireCandidateResolver // 判断是否为Lazy,如果是则使用ProxyFactory创建代理 Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { // 如果非Lazy,则进入实际依赖解析过程 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } }
如上代码所示,首先设置ParameterNameDiscoverer,默认是DefaultParameterNameDiscoverer。然后判断依赖类型,根据依赖类型进行不同的处理。其中在最后一部分中会判断是否为Lazy,如果是Lazy则使用ProxyFactory创建代理返回。如果不是Lazy则进入实际依赖解析过程。
Lazy时,创建代理的过程可以参考方法ContextAnnotationAutowireCandidateResolver的buildLazyResolutionProxy方法。关于AutowireCandidateResolver
如下所示,DefaultListableBeanFactory内部维护了该成员默认是SimpleAutowireCandidateResolver。
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
但是在AnnotationConfigUtils的registerAnnotationConfigProcessors方法中会为容器设置解析器为ContextAnnotationAutowireCandidateResolver,这整个候选解析器是QualifierAnnotationAutowireCandidateResolver的子类。
我们继续看public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException 方法,这是实际解析依赖的入口。
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; } //获取依赖类型,比如interface org.apache.ibatis.session.SqlSessionFactory Class<?> type = descriptor.getDependencyType(); // 这部分处理 @Value 注解 // value如${com.jane.file.baseFilePath} 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()); 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())); } } // 处理集合类型,比如Array Map Collection Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } // 得到候选的、匹配的bean class实例:beanName---bean class 对象 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { // 如果为空且required,则抛出异常NoSuchBeanDefinitionException if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; if (matchingBeans.size() > 1) { // 如果有多个,则根据@Primary和@Priority进行抉择 autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { //如果抉择不出,则可能抛出异常NoUniqueBeanDefinitionException 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(); // 解析得到的依赖bean名称 autowiredBeanName = entry.getKey(); // 解析得到的依赖bean实例-Class对象哦,还需要进一步解析 instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { // 放入autowiredBeanNames,如sqlSessionFactory autowiredBeanNames.add(autowiredBeanName); } // 如果实例是Class对象,则解析为真实的Bean实例对象 if (instanceCandidate instanceof Class) { // beanFactory.getBean(beanName); 也就是getBean的过程 instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); } Object result = instanceCandidate; if (result instanceof NullBean) { if (isRequired(descriptor)) { // 抛出NoSuchBeanDefinitionException raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } result = null; } if (!ClassUtils.isAssignableValue(type, result)) { // 抛出BeanNotOfRequiredTypeException throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass()); } return result; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
如上代码所示,这里可以总结为三个核心方法:
resolveMultipleBeans,处理集合类型,如Array、Map、Collection;
findAutowireCandidates,处理单个对象
descriptor.resolveCandidate(autowiredBeanName, type, this);,将Class对象解析为真实的bean实例,这里会触发getBean的过程。可以说真正的依赖解析是在这里实行的。
————————————————
⑤ @Value
在上面方法中可以看到如下代码,其实就是对@Value注解做了处理。
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
如下所示,AbstractBeanFactory
的resolveEmbeddedValue
方法会尝试使用StringValueResolver
解析得到实际的Value值,比如本文这里的D://myfilemapping/bookrecommend/file
。
【2】postProcessProperties
这里指的是InstantiationAwareBeanPostProcessor的postProcessProperties。前面我们提到过,如果resolvedAutowireMode为0,那么是不会执行autowireByName或者autowireByType的逻辑的。此时@Autowired、@Resource注解就由postProcessProperties方法提供实习。
AutowiredAnnotationBeanPostProcessor处理@Autowired,CommonAnnotationBeanPostProcessor处理@Resource。
如下所示是AutowiredAnnotationBeanPostProcessor
的postProcessProperties方法,该方法首先获取到需要依赖注入的元素,然后调用注入方法得到实例对象。
@Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { // 获取需要依赖注入的元素 InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { // 启动注入过程 metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs; }
① 获取依赖注入的元素
如下所示AutowiredAnnotationBeanPostProcessor
的findAutowiringMetadata
方法找到那些标注了@Autowired注解的字段和方法,提取出来需要进行依赖解析的元素。
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) { // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // Quick check on the concurrent map first, with minimal locking. InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { if (metadata != null) { metadata.clear(pvs); } metadata = buildAutowiringMetadata(clazz); this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; } private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) { return InjectionMetadata.EMPTY; } List<InjectionMetadata.InjectedElement> elements = new ArrayList<>(); Class<?> targetClass = clazz; do { final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>(); ReflectionUtils.doWithLocalFields(targetClass, field -> { MergedAnnotation<?> ann = findAutowiredAnnotation(field); if (ann != null) { if (Modifier.isStatic(field.getModifiers())) { if (logger.isInfoEnabled()) { logger.info("Autowired annotation is not supported on static fields: " + field); } return; } boolean required = determineRequiredStatus(ann); currElements.add(new AutowiredFieldElement(field, required)); } }); ReflectionUtils.doWithLocalMethods(targetClass, method -> { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod); if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { if (Modifier.isStatic(method.getModifiers())) { if (logger.isInfoEnabled()) { logger.info("Autowired annotation is not supported on static methods: " + method); } return; } if (method.getParameterCount() == 0) { if (logger.isInfoEnabled()) { logger.info("Autowired annotation should only be used on methods with parameters: " + method); } } boolean required = determineRequiredStatus(ann); PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new AutowiredMethodElement(method, required, pd)); } }); elements.addAll(0, currElements); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); return InjectionMetadata.forElements(elements, clazz); }
② 依赖注入对象解析
接下来我们再看一下注入过程
// InjectionMetadata#inject 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) { if (logger.isTraceEnabled()) { logger.trace("Processing injected element of bean '" + beanName + "': " + element); } element.inject(target, beanName, pvs); } } } // AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject @Override protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Field field = (Field) this.member; Object value; // 这是缓存机制 if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { 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; // 记录bean与依赖bean的关系 registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new ShortcutDependencyDescriptor( desc, autowiredBeanName, field.getType()); } } } else { this.cachedFieldValue = null; } this.cached = true; } } } // 如果value不为null,则为filed赋值value if (value != null) { ReflectionUtils.makeAccessible(field); field.set(bean, value); } } }
如上代码所示,这里核心逻辑就是 beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
其将会触发依赖解析过程也就是【1】中的第③部分。
③ @Resource
当你controller有@Resource注解时,CommonAnnotationBeanPostProcessor的postProcessProperties方法就会去解析并注入。
@Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex); } return pvs; } private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) { // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // Quick check on the concurrent map first, with minimal locking. // 首先从缓存里面查找 InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); // metadata == null || metadata.targetClass != clazz if (InjectionMetadata.needsRefresh(metadata, clazz)) { // 加锁--双重校验锁 synchronized (this.injectionMetadataCache) { //再次从缓存获取 metadata = this.injectionMetadataCache.get(cacheKey); // 再次进行判断 if (InjectionMetadata.needsRefresh(metadata, clazz)) { if (metadata != null) { metadata.clear(pvs); } // 核心在这里,根据Bean类型获取其需要处理的@Resource元素 metadata = buildResourceMetadata(clazz); // 放入缓存 this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; }
我们看下其收集元素的方法,这里将会收集目标元素如WebServiceRefElement(@WebServiceRef)
、EjbRefElement(@EJB)
及我们常用的ResourceElement(@Resource)
。
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) { if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) { return InjectionMetadata.EMPTY; } List<InjectionMetadata.InjectedElement> elements = new ArrayList<>(); Class<?> targetClass = clazz; do { final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>(); // 从field字段级别收集 ReflectionUtils.doWithLocalFields(targetClass, field -> { if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) { if (Modifier.isStatic(field.getModifiers())) { throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields"); } currElements.add(new WebServiceRefElement(field, field, null)); } else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) { if (Modifier.isStatic(field.getModifiers())) { throw new IllegalStateException("@EJB annotation is not supported on static fields"); } currElements.add(new EjbRefElement(field, field, null)); } else if (field.isAnnotationPresent(Resource.class)) { if (Modifier.isStatic(field.getModifiers())) { throw new IllegalStateException("@Resource annotation is not supported on static fields"); } if (!this.ignoredResourceTypes.contains(field.getType().getName())) { currElements.add(new ResourceElement(field, field, null)); } } }); // 从方法级别收集 ReflectionUtils.doWithLocalMethods(targetClass, method -> { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) { if (Modifier.isStatic(method.getModifiers())) { throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods"); } if (method.getParameterCount() != 1) { throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method); } PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new WebServiceRefElement(method, bridgedMethod, pd)); } else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) { if (Modifier.isStatic(method.getModifiers())) { throw new IllegalStateException("@EJB annotation is not supported on static methods"); } if (method.getParameterCount() != 1) { throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method); } PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new EjbRefElement(method, bridgedMethod, pd)); } else if (bridgedMethod.isAnnotationPresent(Resource.class)) { if (Modifier.isStatic(method.getModifiers())) { throw new IllegalStateException("@Resource annotation is not supported on static methods"); } Class<?>[] paramTypes = method.getParameterTypes(); if (paramTypes.length != 1) { throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method); } if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) { PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new ResourceElement(method, bridgedMethod, pd)); } } } }); elements.addAll(0, currElements); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); return InjectionMetadata.forElements(elements, clazz); }
获取到目标元素后(比如我们@Resource注解的对象),其将会通过如下方法调用栈进行依赖的解析。
// 方法调用栈 InjectionMetadata#inject -> InjectionMetadata.InjectedElement#inject -> CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject -> CommonAnnotationBeanPostProcessor#getResource -> CommonAnnotationBeanPostProcessor#autowireResource -> DefaultListableBeanFactory#resolveDependency
这里我们最后可以看到,其同样走到了DefaultListableBeanFactoryd的resolveDependency方法,不再赘述。
需要注意一点的是,同@Autowired解析依赖的过程一样,这里也实现了lazyLookup 兼容。如果lazyLookup 为true,则创建代理,不触发实际对象解析。
// CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject @Override protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) { return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) : getResource(this, requestingBeanName)); }