通过@Reference
的定义可以发现,这个注解可以作用在字段、方法和注解上
实际只需要实现作用于字段和方法上的情况,作用和@Autowired
类似:填充字段和方法参数。可以直接将@Autowired
作为元注解来使用
但是和@Autowired
最大区别的是:@Reference
作用的字段或方法参数是不会有实现类,需要在属性填充之前将代理类注册到spring容器中;当然可以不使用@Autowired
作为元注解,参照dubbo或者spring的方式自己实现属性填充
实际可以使用的有两个:InstantiationAwareBeanPostProcessor
和BeanFactoryPostProcessor
@Reference定义
定义里的属性可以只做为占位符,大部分都是没有什么用处的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.alibaba.dubbo.config.annotation;
import org.springframework.beans.factory.annotation.Autowired;
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) @Autowired public @interface Reference { ...... }
|
InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor
是BeanPostProcessor
的子接口,添加了bean实例化前回调、及属性填充之前的回调。有三个自己定义的方法
InstantiationAwareBeanPostProcessor
通常是spring内部使用的接口,AutowiredAnnotationBeanPostProcessor
就是用来处理@Autowired
注解的
- postProcessBeforeInstantiation:理论上这里bean还没有实例化。可以提供一个对象来替代内置的对象创建,提供后下面的后处理和属性注入自然都会跳过
- postProcessAfterInstantiation:这里bean已经实例化。返回结果决定是否要执行下面的属性注入
- postProcessProperties:
AutowiredAnnotationBeanPostProcessor
就是在postProcessProperties
方法里查找需要注入的字段,并进行注入的
BeanFactoryPostProcessor
BeanFactoryPostProcessor
是用来处理BeanFactory
中bean定义的接口,可以获取所有的bean定义并修改
BeanFactoryPostProcessor
要早于InstantiationAwareBeanPostProcessor
,这里只是提供了在bean实例化之前修改bean定义的能力,一定不要在这里触发bean的初始化,否则可能会出现莫名其妙的bug
- postProcessBeanFactory:提供
ConfigurableListableBeanFactory
可以从中获取所有bean名和bean定义
具体实现
虽然强调过不要在BeanFactoryPostProcessor
里初始化bean了,但这里场景不同
- 初始化的是接口的代理类,里边不存在对spring的bean依赖,更不可能干扰整个IoC容器
- 只需要保证IoC容器里有实现类即可,具体的字段设置仍然希望借助
@Autowired
的能力,毕竟写的越多bug越多
所以这里使用还是使用了BeanFactoryPostProcessor
,当然这里使用的是beanFactory.registerSingleton
还是不推荐的,可以优化一下转成DefaultListableBeanFactory
然后使用beanFactory.registerBeanDefinition
doWithLocalFields
是spring提供的查找类字段的方法
doWithLocalMethods
是spring提供的查找类方法的方法
registerSingletonObject
如果可以在容器里找到bean实例就跳过注册
ReferenceInvokeHandler
实现了InvocationHandler
,就是jdk的代理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| @Slf4j public class DubboBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { final String[] beanNames = beanFactory.getBeanDefinitionNames(); for (String beanName : beanNames) { final BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); final Class<?> beanClass = ClassCache.find(beanDefinition.getBeanClassName()); if (null != beanClass) { ReflectionUtils.doWithLocalFields(beanClass, field -> { AnnotationAttributes ann = findReferenceAnnotation(field); if (ann != null) { if (Modifier.isStatic(field.getModifiers())) { return; } registerSingletonObject(beanFactory, field.getType()); } }); ReflectionUtils.doWithLocalMethods(beanClass, method -> { final Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } final AnnotationAttributes ann = findReferenceAnnotation(bridgedMethod); if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) { if (Modifier.isStatic(method.getModifiers())) { return; } if (method.getParameterCount() == 0) { return; } final PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass); if (null != pd) { registerSingletonObject(beanFactory, pd.getPropertyType()); } } }); } } }
private AnnotationAttributes findReferenceAnnotation(AccessibleObject accessibleObject) { if (accessibleObject.getAnnotations().length > 0) { return AnnotatedElementUtils.getMergedAnnotationAttributes(accessibleObject, Reference.class); } return null; }
private void registerSingletonObject(ConfigurableListableBeanFactory beanFactory, Class<?> fieldClass) { if (null == fieldClass) { return; } String[] beans = beanFactory.getBeanNamesForType(fieldClass); if (beans.length > 0) { return; }
String fullName = fieldClass.getName(); if (!fieldClass.isInterface()) { log.warn("Reference class: {} is not a interface, Unable to inject implementation class", fullName); return; } Object proxy = Bottle.obtain(fullName); if (null == proxy) { proxy = Proxy.newProxyInstance(beanFactory.getBeanClassLoader(), new Class[]{fieldClass}, new ReferenceInvokeHandler(fieldClass)); Bottle.register(fullName, proxy); beanFactory.registerSingleton(ServiceUtil.formatServiceName(fieldClass.getSimpleName()), proxy); log.debug("Reference class: {} register success", fullName); } } }
|