ReferenceAnnotationBeanPostProcessor inherited AnnotationInjectedBeanPostProcessors that implements the interface postProcessPropertyValues InstantiationAwareBeanPostProcessorAdapter approach, members of the swath @Reference annotated injection ReferenceBean objects:
@Override public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException { InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getName() + " dependencies is failed", ex); } return pvs; }
findInjectionMetadata will identify all fields and methods and packaged into @Reference metadata, metadata.inject method in, calls the method injectElement inject, and then call the method inject AnnotatedFieldElement of:
public class AnnotatedFieldElement extends InjectionMetadata.InjectedElement { private final Field field; private final A annotation; private volatile Object bean; protected AnnotatedFieldElement(Field field, A annotation) { super(field, null); this.field = field; this.annotation = annotation; } @Override protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { Class<?> injectedType = field.getType(); Object injectedObject = getInjectedObject(annotation, bean, beanName, injectedType, this); ReflectionUtils.makeAccessible(field); field.set(bean, injectedObject); } }
protected Object getInjectedObject(A annotation, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) throws Exception { String cacheKey = buildInjectedObjectCacheKey(annotation, bean, beanName, injectedType, injectedElement); Object injectedObject = injectedObjectsCache.get(cacheKey); if (injectedObject == null) { injectedObject = doGetInjectedBean(annotation, bean, beanName, injectedType, injectedElement); // Customized inject-object if necessary injectedObjectsCache.putIfAbsent(cacheKey, injectedObject); } return injectedObject; }
DoGetInjectedBean which is ReferenceAnnotationBeanPostProcessor rewritten:
@Override protected Object doGetInjectedBean(Reference reference, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) throws Exception { String referencedBeanName = buildReferencedBeanName(reference, injectedType); ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referencedBeanName, reference, injectedType, getClassLoader()); cacheInjectedReferenceBean (referenceBean, injectedElement); Object proxy = buildProxy(referencedBeanName, referenceBean, injectedType); return proxy; }
Here you can see a referenceBean construct and return a proxy, real proxy is actually injected