前面对于Service标签的处理已经说明了Dubbo源码分析----Dubbo的Service注解分析
,现在对Reference标签的处理进行解释。
对于Reference标签的解析还是按照前面的分析找到ReferenceAnnotationBeanPostProcessor类这个类是dubbo中AnnotationInjectedBeanPostProcessor的子类,而AnnotationInjectedBeanPostProcessor类又继承了spring的AnnotationInjectedBeanPostProcessor类同时实现了MergedBeanDefinitionPostProcessor类。
其中AnnotationInjectedBeanPostProcessor重载了postProcessPropertyValues跟postProcessMergedBeanDefinition方法,对于这两个方法先进行说明。
- postProcessPropertyValues:这个方法是InstantiationAwareBeanPostProcessor接口中定义的,作用是对实例化之后属性设置之前Bean 的属性值进行修改。调用这个方法的前提是postProcessAfterInstantiation方法返回true,其中postProcessAfterInstantiation方法在InstantiationAwareBeanPostProcessorAdapter默认返回是true。
- postProcessMergedBeanDefinition:这个方法是在MergedBeanDefinitionPostProcessor类中定义的,作用是在Bean合并之后回调用,也就是Bean属性填充完毕之后。
所以按顺序,现在先进入到postProcessPropertyValues方法中。
@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;
}
postProcessPropertyValues方法主要是对Bean中的属性的获取,其中InjectionMetadata对象是spring中用于管理注入元数据的内部类。现在进入findInjectionMetadata方法
private InjectionMetadata findInjectionMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
//生成缓存的cacheKey
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
//检查对应的用于诸如用的元数据是否存在缓存
AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//如果元数据是空的,或者元数据缓存中保存的Class对象不是传入的Class对象
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
//双重检查锁
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
//如果元数据不是null就对其中的属性进行清空
if (metadata != null) {
metadata.clear(pvs);
}
try {
//创建元数据
metadata = buildAnnotatedMetadata(clazz);
//放到缓存中进行保存
this.injectionMetadataCache.put(cacheKey, metadata);
} catch (NoClassDefFoundError err) {
throw new IllegalStateException("Failed to introspect object class [" + clazz.getName() +
"] for annotation metadata: could not find class that it depends on", err);
}
}
}
}
return metadata;
}
上面的逻辑也比较简单,就是先检查缓存和比较Class对象判断是不是同一个,如果缓存为空或者缓存的Class对象不是传入的Class对象,就需要先进行缓存的清楚然后创建InjectionMetadata进行保存。现在对元数据的创建进行解析
private AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) {
//获取AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement
Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass);
//获取AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement
Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass);
//上面的两个集合中的对象都是spring中InjectionMetadata类的内部类InjectedElement的继承类用来保存单个元素
return new AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements);
}
//-------------
private List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> findFieldAnnotationMetadata(final Class<?> beanClass) {
final List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement>();
// 通过反射的工具类,获取当前beanClass中的所有Field,然后通过实现ReflectionUtils类的内部类FieldCallback的实现,来对字段进行处理
ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
//获取field里面的Reference标签
A annotation = getAnnotation(field, getAnnotationType());
//检查标签是不是null
if (annotation != null) {
//field不是static类型的
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("@" + getAnnotationType().getName() + " is not supported on static fields: " + field);
}
return;
}
//创建AnnotatedFieldElement并放到集合中
elements.add(new AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement(field, annotation));
}
}
});
return elements;
}
//--------------------
private List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> findAnnotatedMethodMetadata(final Class<?> beanClass) {
final List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement>();
//获取到beanClass中所有的Method,然后调用实现的ReflectionUtils.MethodCallback类的doWith方法
ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
//寻找method的桥接方法,关于桥接方法这是在Java1.5引入泛型之后,编译器为了向前兼容,生成这个的
Method bridgedMethod = findBridgedMethod(method);
//检查是不是可见的桥接方法
if (!isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
//找到方法上的Reference标签
A annotation = findAnnotation(bridgedMethod, getAnnotationType());
//如果标签不是bull并且找到beanClass中的具体的方法
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
//方法不能是静态的
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("@" + getAnnotationType().getSimpleName() + " annotation is not supported on static methods: " + method);
}
return;
}
//需要有参数
if (method.getParameterTypes().length == 0) {
if (logger.isWarnEnabled()) {
logger.warn("@" + getAnnotationType().getSimpleName() + " annotation should only be used on methods with parameters: " +
method);
}
}
//获取beanClass中指定方法的属性
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
elements.add(new AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement(method, pd, annotation));
}
}
});
return elements;
}
上面分析了从传入的Bean中获取对应的元数据后保存到InjectionMetadata对象中,现在就是进行注入了。inject方法也是一个模板方法,首先调用的InjectionMetadata的inject然后调用AnnotationInjectedBeanPostProcessor类中的内部类实现的inject方法。
//InjectionMetadata中的inject
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
//如果checkedElements为空就使用传入的injectedElements,这里传入的是fieldElements, methodElements两个的组合
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
//迭代然后调用实现的inject方法
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
//-----------------------内部类AnnotatedFieldElement跟AnnotatedMethodElement中的方法
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
//获取类型
Class<?> injectedType = field.getType();
//获取注入之后的对象
Object injectedObject = getInjectedObject(annotation, bean, beanName, injectedType, this);
//如果是私有字段先设置makeAccessible属性
ReflectionUtils.makeAccessible(field);
//给Bean对象设置诸如之后的对象
field.set(bean, injectedObject);
}
//------getInjectedObject方法
protected Object getInjectedObject(A annotation, Object bean, String beanName, Class<?> injectedType,
InjectionMetadata.InjectedElement injectedElement) throws Exception {
//构建缓存对的key
String cacheKey = buildInjectedObjectCacheKey(annotation, bean, beanName, injectedType, injectedElement);
//先查询缓存
Object injectedObject = injectedObjectsCache.get(cacheKey);
//缓存为null
if (injectedObject == null) {
//创建注入之后的对象
injectedObject = doGetInjectedBean(annotation, bean, beanName, injectedType, injectedElement);
// Customized inject-object if necessary
injectedObjectsCache.putIfAbsent(cacheKey, injectedObject);
}
return injectedObject;
}
//------doGetInjectedBean方法
protected Object doGetInjectedBean(Reference reference, Object bean, String beanName, Class<?> injectedType,
InjectionMetadata.InjectedElement injectedElement) throws Exception {
//创建应用Bean 的name,根据接口的名称,类型,group等拼接进行闯进
String referencedBeanName = buildReferencedBeanName(reference, injectedType);
//如果不存在则创建ReferenceBean对象
ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referencedBeanName, reference, injectedType, getClassLoader());
//保存到缓存中
cacheInjectedReferenceBean(referenceBean, injectedElement);
//创建reference的代理类
Object proxy = buildProxy(referencedBeanName, referenceBean, injectedType);
//返回
return proxy;
}
上面就就是对@Reference标签的处理过程,根据获取到的元数据,最后创建一个贴有@Reference标签的接口的代理类。