什么是注解配置?
1.通过BeanConfig 我们自己往容器里面注入配置 一般我们都是像2那样config配置用配置文件配置 跳转
2.通过注解实现我们的服务发布和订阅
注:此篇只会将 ServiceBean初始化 和注解实现订阅原理. 服务发布过程和服务订阅内部过程后面篇幅讲
demo
跟前面二的demo一致 链接
DubboComponentScan
@EnableDubbo注解有一个DubboComponentScan 我们前面说了EnableDubbo只是一个组合注解 方便使用 在类上面打很多注解 我们也可以单独使用
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(DubboComponentScanRegistrar.class)//@Import 注解方式服务发布和订阅切入点<1> public @interface DubboComponentScan { /** * 配置 扫描的包 * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation * declarations e.g.: {@code @DubboComponentScan("org.my.pkg")} instead of * {@code @DubboComponentScan(basePackages="org.my.pkg")}. * * @return the base packages to scan */ String[] value() default {}; /** * 配置要扫描包数组 * Base packages to scan for annotated @Service classes. {@link #value()} is an * alias for (and mutually exclusive with) this attribute. * <p> * Use {@link #basePackageClasses()} for a type-safe alternative to String-based * package names. * * @return the base packages to scan */ String[] basePackages() default {}; /** * 配置要扫描的类的数组 * Type-safe alternative to {@link #basePackages()} for specifying the packages to * scan for annotated @Service classes. The package of each class specified will be * scanned. * * @return classes from the base packages to scan */ Class<?>[] basePackageClasses() default {}; }
DubboComponentScanRegistrar
<1>registerBeanDefinitions
com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScanRegistrar#registerBeanDefinitions
@Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //<2>获取扫描的包集合 Set<String> packagesToScan = getPackagesToScan(importingClassMetadata); // <3>创建 ServiceAnnotationBeanPostProcessor Bean 对象,后续扫描 `@Service` 注解的类,创建对应的 Service Bean 对象 registerServiceAnnotationBeanPostProcessor(packagesToScan, registry); //<4>创建ReferenceAnnotationBeanPostProcessor bean对象 后续扫描 @Reference 的类 创建对应的 Reference Bean 对象 registerReferenceAnnotationBeanPostProcessor(registry); }
<2>getPackagesToScan
com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScanRegistrar#registerBeanDefinitions
->
com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScanRegistrar#getPackagesToScan
private Set<String> getPackagesToScan(AnnotationMetadata metadata) { //// 获得 @DubboComponentScan 注解 AnnotationAttributes attributes = AnnotationAttributes.fromMap( metadata.getAnnotationAttributes(DubboComponentScan.class.getName())); //获取配置的basePackages值 String[] basePackages = attributes.getStringArray("basePackages"); //获取注解配置的basePackageClasses Class<?>[] basePackageClasses = attributes.getClassArray("basePackageClasses"); //获取注解配置的value值 String[] value = attributes.getStringArray("value"); //将配置的value添加到 packagesToScan 集合中 Set<String> packagesToScan = new LinkedHashSet<String>(Arrays.asList(value)); //将配置的basePackages加到集合 packagesToScan.addAll(Arrays.asList(basePackages)); //将配置的class加到 集合中 for (Class<?> basePackageClass : basePackageClasses) { packagesToScan.add(ClassUtils.getPackageName(basePackageClass)); } //如果没有配置 if (packagesToScan.isEmpty()) { //则默认获取注解类所在包 return Collections.singleton(ClassUtils.getPackageName(metadata.getClassName())); } return packagesToScan; }
<3>registerServiceAnnotationBeanPostProcessor
/** * 创建扫描@Service的Processor * * @param packagesToScan packages to scan without resolving placeholders * @param registry {@link BeanDefinitionRegistry} * @since 2.5.8 */ private void registerServiceAnnotationBeanPostProcessor(Set<String> packagesToScan, BeanDefinitionRegistry registry) { //<5>获得ServiceAnnotationBeanPostProcessor的Builder 此类实现了spring BeanDefinitionRegistryPostProcessor 我们可以像容器自定义创建bean 调用由spring调度 BeanDefinitionBuilder builder = rootBeanDefinition(ServiceAnnotationBeanPostProcessor.class); //告诉spring 通过构造函数初始化 并传入扫描的包集合 builder.addConstructorArgValue(packagesToScan); builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry); }
<4>registerReferenceAnnotationBeanPostProcessor
com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScanRegistrar#registerBeanDefinitions
->
com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScanRegistrar#registerReferenceAnnotationBeanPostProcessor
/** * 注册处理@Reference的处理器 * * @param registry {@link BeanDefinitionRegistry} */ private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) { //<11> ReferenceAnnotationBeanPostProcessor 这个间接实现了MergedBeanDefinitionPostProcessor //spring在创建 注册 因为他间接实现了上面的接口 所以在spring初始化过程中 我们可以做一些事情 BeanRegistrar.registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class); }
ServiceAnnotationBeanPostProcessor
<5>postProcessBeanDefinitionRegistry
由spring调度因为实现了BeanDefinitionRegistryPostProcessor
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#postProcessBeanDefinitionRegistry
@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { //<6>避免扫描包配置的占位符 转换一次 如:${} Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan); if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) { //<7>扫描包 registerServiceBeans(resolvedPackagesToScan, registry); } else { if (logger.isWarnEnabled()) { logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!"); } } }
<6>postProcessBeanDefinitionRegistry
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#postProcessBeanDefinitionRegistry
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#resolvePackagesToScan
private Set<String> resolvePackagesToScan(Set<String> packagesToScan) { Set<String> resolvedPackagesToScan = new LinkedHashSet<String>(packagesToScan.size()); //遍历 for (String packageToScan : packagesToScan) { if (StringUtils.hasText(packageToScan)) { // environment.resolvePlaceholders的作用是避免我们传的是占位符${packageToscan} String resolvedPackageToScan = environment.resolvePlaceholders(packageToScan.trim()); resolvedPackagesToScan.add(resolvedPackageToScan); } } return resolvedPackagesToScan; }
<7>registerServiceBeans
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#postProcessBeanDefinitionRegistry
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#registerServiceBeans
private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) { //继承ClassPathBeanDefinitionScanner //实现了EnvironmentAware, // ResourceLoaderAware, BeanClassLoaderAware接口 注入的environment,resourceLoader DubboClassPathBeanDefinitionScanner scanner = new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader); //<8>获得 BeanNameGenerator 对象,并设置 beanNameGenerator 到 scanner 中 返回的是AnotationBeanNameGeenerator BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry); //设置BeanNameGenerator到scanner scanner.setBeanNameGenerator(beanNameGenerator); //要扫描的注解类 scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class)); //循环咋配置的扫描包里面扫描 for (String packageToScan : packagesToScan) { // 执行扫描 scanner.scan(packageToScan); // 获取扫描到的bean definition定义 Set<BeanDefinitionHolder> beanDefinitionHolders = findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator); if (!CollectionUtils.isEmpty(beanDefinitionHolders)) { for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) { //<9>遍历注册 beanDefinitionHolders就是扫描到的打了dubbo Service的类 registerServiceBean(beanDefinitionHolder, registry, scanner); } if (logger.isInfoEnabled()) { logger.info(beanDefinitionHolders.size() + " annotated Dubbo's @Service Components { " + beanDefinitionHolders + " } were scanned under package[" + packageToScan + "]"); } } else { if (logger.isWarnEnabled()) { logger.warn("No Spring Bean annotating Dubbo's @Service was found under package[" + packageToScan + "]"); } } } }
<8>resolveBeanNameGenerator
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#postProcessBeanDefinitionRegistry
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#registerServiceBeans
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#resolveBeanNameGenerator
private BeanNameGenerator resolveBeanNameGenerator(BeanDefinitionRegistry registry) { BeanNameGenerator beanNameGenerator = null; //不知道干嘛的 我打断点默认会进来 但是获取的beanNameGenerator是空 if (registry instanceof SingletonBeanRegistry) { SingletonBeanRegistry singletonBeanRegistry = SingletonBeanRegistry.class.cast(registry); beanNameGenerator = (BeanNameGenerator) singletonBeanRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); } if (beanNameGenerator == null) { if (logger.isInfoEnabled()) { logger.info("BeanNameGenerator bean can't be found in BeanFactory with name [" + CONFIGURATION_BEAN_NAME_GENERATOR + "]"); logger.info("BeanNameGenerator will be a instance of " + AnnotationBeanNameGenerator.class.getName() + " , it maybe a potential problem on bean name generation."); } //最终返回的是介个 beanNameGenerator = new AnnotationBeanNameGenerator(); } return beanNameGenerator; }
<9>registerServiceBean
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#postProcessBeanDefinitionRegistry
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#registerServiceBeans
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#registerServiceBean
private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry, DubboClassPathBeanDefinitionScanner scanner) { //获得对应 service class对象 Class<?> beanClass = resolveClass(beanDefinitionHolder); //获得class对象上的注解对象 Service service = findAnnotation(beanClass, Service.class); //获得class对象的结果class Class<?> interfaceClass = resolveServiceInterfaceClass(beanClass, service); //获得beanName String annotatedServiceBeanName = beanDefinitionHolder.getBeanName(); //<10>获得serviceBean的 定义 AbstractBeanDefinition serviceBeanDefinition = buildServiceBeanDefinition(service, interfaceClass, annotatedServiceBeanName); // 为ServiceBean生成beanName 如:ServiceBean:com.alibaba.dubbo.demo.DemoService String beanName = generateServiceBeanName(service, interfaceClass, annotatedServiceBeanName); //检查名字是否重复 如果没有存在 则进行注册 至此 我们的ServiceBean就注册到spring 容器了 让我们回到<1> 看<4>@Refrence的初始化 if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean registry.registerBeanDefinition(beanName, serviceBeanDefinition); if (logger.isInfoEnabled()) { logger.info("The BeanDefinition[" + serviceBeanDefinition + "] of ServiceBean has been registered with name : " + beanName); } } else { if (logger.isWarnEnabled()) { logger.warn("The Duplicated BeanDefinition[" + serviceBeanDefinition + "] of ServiceBean[ bean name : " + beanName + "] was be found , Did @DubboComponentScan scan to same package in many times?"); } } }
<10>buildServiceBeanDefinition
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#postProcessBeanDefinitionRegistry
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#registerServiceBeans
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#registerServiceBean
private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class<?> interfaceClass, String annotatedServiceBeanName) { BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class); AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); //通过他后续可以向对象属性注入值 MutablePropertyValues propertyValues = beanDefinition.getPropertyValues(); //service的属性 也是@Service的可配置项目 String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol", "interface", "interfaceName"); propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(service, environment, ignoreAttributeNames)); //设置ServiceBean 的ref属性值为 @Service 注解所打bean的名字 如 demoServiceImpl addPropertyReference(builder, "ref", annotatedServiceBeanName); // 设置serviceBean 的interface属性 为@Seervice所打bean的接口全名称 如:com.alibaba.dubbo.demo.DemoService builder.addPropertyValue("interface", interfaceClass.getName()); /** * 获取@service注解配置的 provider设置到ServiceBean * addPropertyReference 所以配置的beanName注入的是容器里面对应的bean */ String providerConfigBeanName = service.provider(); if (StringUtils.hasText(providerConfigBeanName)) { addPropertyReference(builder, "provider", providerConfigBeanName); } /** * 获取@service注解配置的 monitor设置到ServiceBean * addPropertyReference 所以配置的beanName注入的是容器里面对应的bean */ String monitorConfigBeanName = service.monitor(); if (StringUtils.hasText(monitorConfigBeanName)) { addPropertyReference(builder, "monitor", monitorConfigBeanName); } /** * 获取@service注解配置的application设置到ServiceBean * addPropertyReference 所以配置的beanName注入的是容器里面对应的bean */ String applicationConfigBeanName = service.application(); if (StringUtils.hasText(applicationConfigBeanName)) { addPropertyReference(builder, "application", applicationConfigBeanName); } /** * 获取@service注解配置的module设置到ServiceBean * addPropertyReference 所以配置的beanName注入的是容器里面对应的bean */ String moduleConfigBeanName = service.module(); if (StringUtils.hasText(moduleConfigBeanName)) { addPropertyReference(builder, "module", moduleConfigBeanName); } /** * 获取@service注解配置的module设置到ServiceBean * 因为可以配置数组 */ String[] registryConfigBeanNames = service.registry(); List<RuntimeBeanReference> registryRuntimeBeanReferences = toRuntimeBeanReferences(registryConfigBeanNames); if (!registryRuntimeBeanReferences.isEmpty()) { builder.addPropertyValue("registries", registryRuntimeBeanReferences); } /** * 获取@service注解配置的protocol设置到ServiceBean * 因为可以配置数组 */ String[] protocolConfigBeanNames = service.protocol(); List<RuntimeBeanReference> protocolRuntimeBeanReferences = toRuntimeBeanReferences(protocolConfigBeanNames); if (!protocolRuntimeBeanReferences.isEmpty()) { builder.addPropertyValue("protocols", protocolRuntimeBeanReferences); } /** * 获取@service注解配置的methods设置到ServiceBean * 因为可以配置数组 */ Method[] methods = service.methods(); //将method对象转换成methodConfig List<MethodConfig> methodConfigs = MethodConfig.constructMethodConfig(methods); if (!methodConfigs.isEmpty()) { builder.addPropertyValue("methods", methodConfigs); } /** * 返回 这个时候definition定义好了 告诉spring 如何创建ServiceBean 并初始化我们注解配置的属性 我们回到<9> */ return builder.getBeanDefinition(); }
ReferenceAnnotationBeanPostProcessor
类图
BeanProcess5大对象调用时机与作用可以参考:链接
虽然继承了InstantiationAwareBeanPostProcessorAdapter 但是并没有做特殊处理我们直接看SmartInstantiationAwareBeanPostProcessor的实现
类源码
public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBeanPostProcessor<Reference> implements ApplicationContextAware, ApplicationListener { /** } }
<11>构造AnnotationInjectedBeanPostProcessor()
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#AnnotationInjectedBeanPostProcessor
public AnnotationInjectedBeanPostProcessor() { //<12>获取到泛型参数的值 extends AnnotationInjectedBeanPostProcessor<Reference> 就是Reference.class 可以看上面类图和类结构 //初始化后我们接着看<13> 此方法由spring调度 可以在创建实例后 进行调用我们可以改变属性 this.annotationType = resolveGenericType(getClass()); }
<12>resolveGenericType
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#AnnotationInjectedBeanPostProcessor
->
com.alibaba.dubbo.config.spring.util.ClassUtils#resolveGenericType
public static <T> Class<T> resolveGenericType(Class<?> declaredClass) { ParameterizedType parameterizedType = (ParameterizedType) declaredClass.getGenericSuperclass(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); return (Class<T>) actualTypeArguments[0]; }
<13>postProcessMergedBeanDefinition
此方法为MergedBeanDefinitionPostProcessor实现BeanProcess5大对象调用时机与作用可以参考:链接
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#postProcessMergedBeanDefinition
/** * MergedBeanDefinitionPostProcessor接口的实现 根据 * 作用在bean实例化完毕后调用 可以用来修改merged BeanDefinition的一些properties 或者用来给后续回调中缓存一些meta信息使用 * 这个算是将merged BeanDefinition暴露出来的一个回调 * 在bean实例化之前初始化之前调用 主要用来改变打了@refrece的的属性的值 * @param beanDefinition * @param beanType * @param beanName */ @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { if (beanType != null) { //<14>反射获得指定bean 打了@Refrence的filed和method元数据封装到InjectionMetadata //注:这里返回的是AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null); // 将注入元数据信息保存到 RootBeanDefinition#externallyManagedConfigMembers 属性中 //这里将类里面打了@Refrence的filed和method元素都拿到了 我们继续看<18> metadata.checkConfigMembers(beanDefinition); } }
<14>findInjectionMetadata
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#postProcessMergedBeanDefinition
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#findInjectionMetadata
public InjectionMetadata findInjectionMetadata(String beanName, Class<?> clazz, PropertyValues pvs) { // 获得缓存key 这里获取的是beanName比如studentServiceImpl 如果没有则获取className String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // 判断缓存是否存在避免每次重复加载 AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { //避免缓存穿透 metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { //pvs是null前面写的传null if (metadata != null) { metadata.clear(pvs); } try { //<15>主要是反射获取打了@Refrence的filed和method并封装到metaData 返回的AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata继承InjectionMetadata 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; }
<15>buildAnnotatedMetadata
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#postProcessMergedBeanDefinition
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#findInjectionMetadata
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata
private AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) { //<16>反射获得所有Filed 只会查找打了@Refrence注解的filed beaClass在<11>处就被初始化了 Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass); //<17>反射获得所有method 只会查找打了@Reefrence注解的public beaClass在<11>处就被初始化了 Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass); //通过内部类封装 AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata return new AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements); }
<16>findFieldAnnotationMetadata
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#postProcessMergedBeanDefinition
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#findInjectionMetadata
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#findFieldAnnotationMetadata
private List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> findFieldAnnotationMetadata(final Class<?> beanClass) { final List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement>(); //反射找到打上了指定出的filed ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() { @Override public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { //getAnnotationType <11>处初始化 A annotation = getAnnotation(field, getAnnotationType()); if (annotation != null) { if (Modifier.isStatic(field.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn("@" + getAnnotationType().getName() + " is not supported on static fields: " + field); } return; } elements.add(new AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement(field, annotation)); } } }); return elements; }
<17>findAnnotatedMethodMetadata
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#postProcessMergedBeanDefinition
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#findInjectionMetadata
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#findAnnotatedMethodMetadata
private List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> findAnnotatedMethodMetadata(final Class<?> beanClass) { final List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement>(); //反射处理打上了getAnnotationType 的set方法 ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Method bridgedMethod = findBridgedMethod(method); if (!isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } A annotation = findAnnotation(bridgedMethod, getAnnotationType()); 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); } } PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass); elements.add(new AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement(method, pd, annotation)); } } }); return elements; }
<18>postProcessPropertyValues
因为实现了 InstantiationAwareBeanPostProcessor 由spring调度
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#postProcessPropertyValues
/** * 这里是在spring处理完默认的成员属性,应用到指定的bean之前进行回调,可以用来检查和修改属性,最终返回的PropertyValues会应用到bean中 * @Autowired、@Resource等就是根据这个回调来实现最终注入依赖的属性的。 * 重写的 InstantiationAwareBeanPostProcessor接口 在 MergedBeanDefinitionPostProcessor 后调用 * 已经初始化了打上了@Refrence 的属性到metaData * @param pvs * @param pds * @param bean * @param beanName * @return * @throws BeanCreationException */ @Override public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException { /** * 这里是读取缓存 也就是读取到打上了@Refrece的filed和method元数据信息 * 返回的AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata继承InjectionMetadata */ InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs); try { //<19>代理类生成 并设置到PropertyValues完成注入 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; }
<22>getInjectedObject
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
protected Object getInjectedObject(A annotation, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) throws Exception { //生成缓存key 如:ServiceBean:com.alibaba.dubbo.demo.DemoService#source=com.alibaba.dubbo.demo.DemoService consumer.StudentServiceImpl.demoService#attributes={} String cacheKey = buildInjectedObjectCacheKey(annotation, bean, beanName, injectedType, injectedElement); //尝试从缓存获取 默认没有 //是为了我们多个类都@Refrece同一个对象 而不用重新构建代理对象 Object injectedObject = injectedObjectsCache.get(cacheKey); if (injectedObject == null) { //<23>获得代理对象 被子类重写 com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor.doGetInjectedBean injectedObject = doGetInjectedBean(annotation, bean, beanName, injectedType, injectedElement); // Customized inject-object if necessary injectedObjectsCache.putIfAbsent(cacheKey, injectedObject); } //返回代理对象 return injectedObject; }
AnnotatedInjectionMetadata
此类为AnnotationInjectedBeanPostProcessor 内部类
<19>inject
因为继承InjectionMetadata 并没有重写inject 所以调用的是InjectionMetadata 的
org.springframework.beans.factory.annotation.InjectionMetadata#inject
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable { Collection<InjectionMetadata.InjectedElement> elementsToIterate = this.checkedElements != null ? this.checkedElements : this.injectedElements; if (!((Collection)elementsToIterate).isEmpty()) { boolean debug = logger.isDebugEnabled(); InjectionMetadata.InjectedElement element; /** * 注意看<15>处 这里是多态 分别调用的是 * AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement<20> * AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement<21> * 的inject<20> */ for(Iterator var6 = ((Collection)elementsToIterate).iterator(); var6.hasNext(); element.inject(target, beanName, pvs)) { element = (InjectionMetadata.InjectedElement)var6.next(); if (debug) { logger.debug("Processing injected element of bean '" + beanName + "': " + element); } } } }
AnnotatedFieldElement
<20>inject
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement#inject
@Override protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { //获取filed的元素聚 Class<?> injectedType = field.getType(); //传入注解 bean和beanName注入类型信息 //com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.getInjectedObject //<22>获得代理对象 injectedBean = getInjectedObject(annotation, bean, beanName, injectedType, this); ReflectionUtils.makeAccessible(field); //注入 field.set(bean, injectedBean); }
AnnotatedMethodElement
<21>inject
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
@Override protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { //获取注入类的类型 Class<?> injectedType = pd.getPropertyType(); //<22>此类为内部类 这类调用的是:com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.getInjectedObject injectedBean = getInjectedObject(annotation, bean, beanName, injectedType, this); ReflectionUtils.makeAccessible(method); //注入代理对象 method.invoke(bean, injectedBean); }
ReferenceAnnotationBeanPostProcessor
<23>doGetInjectedBean
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
@Override protected Object doGetInjectedBean(Reference reference, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) throws Exception { //获得beanName引用的baan的如:ServiceBean:com.alibaba.dubbo.demo.DemoService String referencedBeanName = buildReferencedBeanName(reference, injectedType); //<233>构建RefrenceBean的实例 ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referencedBeanName, reference, injectedType, getClassLoader()); //加入到缓存 供后续使用 cacheInjectedReferenceBean(referenceBean, injectedElement); //<29>构建代理对象 Object proxy = buildProxy(referencedBeanName, referenceBean, injectedType); return proxy; }
<29>buildProxy
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildProxy
private Object buildProxy(String referencedBeanName, ReferenceBean referenceBean, Class<?> injectedType) { //<30>创建jdk动态代理的Handler 这里创建的ReferenceBeanInvocationHandler 实现了InvocationHandler InvocationHandler handler = buildInvocationHandler(referencedBeanName, referenceBean); //jdk动态代理 Object proxy = Proxy.newProxyInstance(getClassLoader(), new Class[]{injectedType}, handler); return proxy; }
<30>buildProxy
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildProxy
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildInvocationHandler
private InvocationHandler buildInvocationHandler(String referencedBeanName, ReferenceBean referenceBean) { //从缓存获取 避免多次订阅耗时 ReferenceBeanInvocationHandler handler = localReferenceBeanInvocationHandlerCache.get(referencedBeanName); if (handler == null) { handler = new ReferenceBeanInvocationHandler(referenceBean); } //判断容器是否有这个bean if (applicationContext.containsBean(referencedBeanName)) { // Is local @Service Bean or not ? // ReferenceBeanInvocationHandler's initialization has to wait for current local @Service Bean has been exported. localReferenceBeanInvocationHandlerCache.put(referencedBeanName, handler); } else { //<31>实现服务订阅 handler.init(); } //返回handlerAnnotationInjectedBeanPostProcessor return handler; }
<31>init
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildProxy
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildInvocationHandler
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor.ReferenceBeanInvocationHandler#init
private void init() { this.bean = referenceBean.get(); }
回到第一篇可以看到 做了这么多 最终只是替代了我们api配置 简介了配置
<233>buildReferenceBeanIfAbsent
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildReferenceBeanIfAbsent
private ReferenceBean buildReferenceBeanIfAbsent(String referencedBeanName, Reference reference, Class<?> referencedType, ClassLoader classLoader) throws Exception { //从缓存获取 ReferenceBean key:ServiceBean:com.alibaba.dubbo.demo.DemoService ReferenceBean<?> referenceBean = referenceBeanCache.get(referencedBeanName); if (referenceBean == null) { //创建一个构件RefenceBean的Builder 建造者模式 ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder .create(reference, classLoader, applicationContext) .interfaceClass(referencedType); //<24>RefenceBean referenceBean = beanBuilder.build(); //加入到缓存 referenceBeanCache.put(referencedBeanName, referenceBean); } return referenceBean; }
<24>build
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildReferenceBeanIfAbsent
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AbstractAnnotationConfigBeanBuilder#build
public final B build() throws Exception { //空实现 checkDependencies(); //<25>被子类重写 反射创建一个空的ReferenceBean B bean = doBuild(); //<26>设置配置信息 configureBean(bean); if (logger.isInfoEnabled()) { logger.info("The bean[type:" + bean.getClass().getSimpleName() + "] has been built."); } return bean; }
<25>doBuild
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildReferenceBeanIfAbsent
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AbstractAnnotationConfigBeanBuilder#build
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceBeanBuilder#doBuild
protected ReferenceBean doBuild() { return new ReferenceBean<Object>(); }
<26>configureBean
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildReferenceBeanIfAbsent
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AbstractAnnotationConfigBeanBuilder#build
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AbstractAnnotationConfigBeanBuilder#configureBean
protected void configureBean(B bean) throws Exception { //<27>前置配置 被子类重写com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceBeanBuilder.preConfigureBean //暂时不造干嘛的 preConfigureBean(annotation, bean); //初始化RegistryConfigs 将注解上配置的RegistryConfigs 设置到RefrenceBean configureRegistryConfigs(bean); //初始化MonitorConfig 将注解上配置的MonitorConfig 设置到RefrenceBean configureMonitorConfig(bean); //初始化ApplicationConfig 将注解上配置的ApplicationConfig 设置到RefrenceBean configureApplicationConfig(bean); //初始化ModuleConfig 将注解上配置的ModuleConfig 设置到RefrenceBean configureModuleConfig(bean); //<28>后置配置 被子类重写 postConfigureBean(annotation, bean); }
<27>preConfigureBean
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildReferenceBeanIfAbsent
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AbstractAnnotationConfigBeanBuilder#build
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AbstractAnnotationConfigBeanBuilder#configureBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceBeanBuilder#preConfigureBean
protected void preConfigureBean(Reference reference, ReferenceBean referenceBean) { Assert.notNull(interfaceClass, "The interface class must set first!"); DataBinder dataBinder = new DataBinder(referenceBean); // Register CustomEditors for special fields dataBinder.registerCustomEditor(String.class, "filter", new StringTrimmerEditor(true)); dataBinder.registerCustomEditor(String.class, "listener", new StringTrimmerEditor(true)); dataBinder.registerCustomEditor(Map.class, "parameters", new PropertyEditorSupport() { public void setAsText(String text) throws java.lang.IllegalArgumentException { // Trim all whitespace String content = StringUtils.trimAllWhitespace(text); if (!StringUtils.hasText(content)) { // No content , ignore directly return; } // replace "=" to "," content = StringUtils.replace(content, "=", ","); // replace ":" to "," content = StringUtils.replace(content, ":", ","); // String[] to Map Map<String, String> parameters = CollectionUtils.toStringMap(commaDelimitedListToStringArray(content)); setValue(parameters); } }); // Bind annotation attributes dataBinder.bind(new AnnotationPropertyValuesAdapter(reference, applicationContext.getEnvironment(), IGNORE_FIELD_NAMES)); }
<28>postConfigureBean
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor.Annotated(Filed|Method)Element#inject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor#getInjectedObject
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#buildReferenceBeanIfAbsent
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AbstractAnnotationConfigBeanBuilder#build
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.AbstractAnnotationConfigBeanBuilder#configureBean
->
com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceBeanBuilder#postConfigureBean
@Override protected void postConfigureBean(Reference annotation, ReferenceBean bean) throws Exception { bean.setApplicationContext(applicationContext); //@Refrence设置注解配置的Interface configureInterface(annotation, bean); //设置@Refrence设置的consumer配置 configureConsumerConfig(annotation, bean); //设置@Refrence设置的methods配置 到RefrenceBean configureMethodConfig(annotation, bean); //调用RefreceBean的afterPropertiesSet方法 至此RefrenceBean就初始化完了 现在回到<23> 继续看<29> bean.afterPropertiesSet(); }
总结
@ServcieBean初始化
1.通过打上@DubboComponentScan注解配置扫描信息
2.此注解打了@Import注解以DubboComponentScanRegistrar作为切入点
3.通过DubboClassPathBeanDefinitionScanner继承了ClassPathBeanDefinitionScanner 对指定包@Service注解扫描获得beanDefinition
3.然后通过从@Service注解上的配置 加载容器里面的各个config做初始化动作
@Refrence
1.通过打上@DubboComponentScan注解配置扫描信息
2.此注解打了@Import注解以DubboComponentScanRegistrar作为切入点
3.通过注册实现了spring MergedBeanDefinitionPostProcessor 可以在bean创建之后初始化之前做一些处理
4.内部活动bean的所有 打上了@Refrece的filed和method元数据
5.3步骤bean还实现了InstantiationAwareBeanPostProcessor接口 可以在spring bean初始化后改变属性值
6.通过4的元数据反射初始化RefrenceBean的实例并通过get方法获取代理对象 然后再通过@Refrence接口通过jdk动态代理再生成一层代理 内部调用RefrenceBean生成的代理对象
最新评论