ServiceAnnotationBeanPostProcessor源码分析

ServiceAnnotationBeanPostProcessor实现了BeanDefinitionRegistryPostProcessor接口

public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,ResourceLoaderAware, BeanClassLoaderAware {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final Set<String> packagesToScan;

    private Environment environment;

    private ResourceLoader resourceLoader;

    private ClassLoader classLoader;

    public ServiceAnnotationBeanPostProcessor(String... packagesToScan) {
        this(Arrays.asList(packagesToScan));
    }

    public ServiceAnnotationBeanPostProcessor(Collection<String> packagesToScan) {
        this(new LinkedHashSet<String>(packagesToScan));
    }

    public ServiceAnnotationBeanPostProcessor(Set<String> packagesToScan) {
        this.packagesToScan = packagesToScan;
    }
	//看这里
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		//获取最终要扫描包路径
        Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan);
		
        if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) {
        	//扫描包路径下所有的类,注册有Service注解的类到spring容器中
            registerServiceBeans(resolvedPackagesToScan, registry);
        } else {
            if (logger.isWarnEnabled()) {
                logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!");
            }
        }

    }
    
    private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
		//实例化DubboClassPathBeanDefinitionScanner,继承自ClassPathBeanDefinitionScanner
        DubboClassPathBeanDefinitionScanner scanner =
                new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);
		//得到一个beanName生成器
        BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);
		
        scanner.setBeanNameGenerator(beanNameGenerator);
		//只扫描Service注解
        scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));
		//循环所有的包路径
        for (String packageToScan : packagesToScan) {

            // Registers @Service Bean first
            //调用父类ClassPathBeanDefinitionScanner的scan方法,扫描对应注解的类并实例化为BeanDefinition注册到容器中
            //这里注册的bean具有spring的特性
            scanner.scan(packageToScan);
			
            // Finds all BeanDefinitionHolders of @Service whether @ComponentScan scans or not.
            //返回包路径下所有Service注解对应的类的BeanDefinitionHolder
            Set<BeanDefinitionHolder> beanDefinitionHolders =
                    findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);
			
            if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
				//处理Service注解的BeanDefinitionHolder并注册到spring容器中
				//这里注册的bean具有dubbo的特性
                for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
                    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 + "]");
                }

            }

        }

    }
    
    private BeanNameGenerator resolveBeanNameGenerator(BeanDefinitionRegistry registry) {

        BeanNameGenerator beanNameGenerator = null;
		
        if (registry instanceof SingletonBeanRegistry) {
            SingletonBeanRegistry singletonBeanRegistry = SingletonBeanRegistry.class.cast(registry);
            //从spring容器中获取beanName为org.springframework.context.annotation.internalConfigurationBeanNameGenerator的beanNameGenerator
            beanNameGenerator = (BeanNameGenerator) singletonBeanRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
        }
		//如果没有,实例化一个AnnotationBeanNameGenerator返回
        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;

    }

    private Set<BeanDefinitionHolder> findServiceBeanDefinitionHolders(
            ClassPathBeanDefinitionScanner scanner, String packageToScan, BeanDefinitionRegistry registry,
            BeanNameGenerator beanNameGenerator) {
		//调用父类ClassPathBeanDefinitionScanner的findCandidateComponents方法扫描包路径所有有Service注解的修饰的类型包装为BeanDefinition返回
        Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents(packageToScan);

        Set<BeanDefinitionHolder> beanDefinitionHolders = new LinkedHashSet<BeanDefinitionHolder>(beanDefinitions.size());
		//生成beanName, 把BeanDefinition包装为BeanDefinitionHolder 返回
        for (BeanDefinition beanDefinition : beanDefinitions) {

            String beanName = beanNameGenerator.generateBeanName(beanDefinition, registry);
            BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(beanDefinition, beanName);
            beanDefinitionHolders.add(beanDefinitionHolder);

        }

        return beanDefinitionHolders;

    }

    private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry,
                                     DubboClassPathBeanDefinitionScanner scanner) {
		
		//返回类名
        Class<?> beanClass = resolveClass(beanDefinitionHolder);
		//获取Service注解
        Service service = findAnnotation(beanClass, Service.class);
		//获取实现的接口
        Class<?> interfaceClass = resolveServiceInterfaceClass(beanClass, service);
		//获取beanName
        String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();
		//使用Service注解的属性,创建一个新的BeanDefinition  (ServiceBeanDefinition)
        AbstractBeanDefinition serviceBeanDefinition =
                buildServiceBeanDefinition(service, interfaceClass, annotatedServiceBeanName);

        // ServiceBean Bean name
        //使用Service注解的group属性 version属性 interfaceClass 生成beanName (ServiceBeanName)
        String beanName = generateServiceBeanName(service, interfaceClass, annotatedServiceBeanName);
		
		//检查是否重复生成
        if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
        	//将该BeanDefinition 注册到spring容器中。
            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?");
            }

        }

    }

    private String generateServiceBeanName(Service service, Class<?> interfaceClass, String annotatedServiceBeanName) {
		//限于篇幅,不跟进去看到了,挺简单的。environment用于解析占位符
        ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(service, interfaceClass, environment);

        return builder.build();
    }
	
    private Class<?> resolveServiceInterfaceClass(Class<?> annotatedServiceBeanClass, Service service) {
		//注解可以配置实现的接口
        Class<?> interfaceClass = service.interfaceClass();
		//没有配置实现的接口 默认为void.clas
        if (void.class.equals(interfaceClass)) {

            interfaceClass = null;
			//获取配置的接口名
            String interfaceClassName = service.interfaceName();
			
            if (StringUtils.hasText(interfaceClassName)) {
            	//是否存在该接口
                if (ClassUtils.isPresent(interfaceClassName, classLoader)) {
                	//存在返回该接口的class对象
                    interfaceClass = resolveClassName(interfaceClassName, classLoader);
                }
            }

        }
		//没有配置实现的接口,拿到所有实现的接口。返回第一个
        if (interfaceClass == null) {
            // Find all interfaces from the annotated class
            // To resolve an issue : https://github.com/apache/incubator-dubbo/issues/3251
            Class<?>[] allInterfaces = ClassUtils.getAllInterfacesForClass(annotatedServiceBeanClass);

            if (allInterfaces.length > 0) {
                interfaceClass = allInterfaces[0];
            }

        }
		//必须实现接口
        Assert.notNull(interfaceClass,
                "@Service interfaceClass() or interfaceName() or interface class must be present!");

        Assert.isTrue(interfaceClass.isInterface(),
                "The type that was annotated @Service is not an interface!");

        return interfaceClass;
    }

    private Class<?> resolveClass(BeanDefinitionHolder beanDefinitionHolder) {

        BeanDefinition beanDefinition = beanDefinitionHolder.getBeanDefinition();

        return resolveClass(beanDefinition);

    }

    private Class<?> resolveClass(BeanDefinition beanDefinition) {

        String beanClassName = beanDefinition.getBeanClassName();

        return resolveClassName(beanClassName, classLoader);

    }

    private Set<String> resolvePackagesToScan(Set<String> packagesToScan) {
    	//获取到从注解配置上拿到的要扫描的包的值
        Set<String> resolvedPackagesToScan = new LinkedHashSet<String>(packagesToScan.size());
        for (String packageToScan : packagesToScan) {
            if (StringUtils.hasText(packageToScan)) {
            	//可以使用占位符配置包名,在配置属性中加入占位符对应的值
            	//从environment找到所有配置属性,解析占位符,返回对应配置值。
            	//非占位符形式${},则直接直接返回
                String resolvedPackageToScan = environment.resolvePlaceholders(packageToScan.trim());
                resolvedPackagesToScan.add(resolvedPackageToScan);
            }
        }
        return resolvedPackagesToScan;
    }
	
    private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class<?> interfaceClass,
                                                              String annotatedServiceBeanName) {
		//这里的传入的class对象是 ServiceBean!不是原本的类型对象
        BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class);
		
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
		
        MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
		//Service注解这些属性的默认值忽略掉,不会使用默认值进行属性填充
        String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol",
                "interface", "interfaceName");
		
        propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(service, environment, ignoreAttributeNames));
		
        //添加ref属性,可以是占位符的形式,从environment中取到配置属性,解析占位符
        addPropertyReference(builder, "ref", annotatedServiceBeanName);
        //添加interface属性
        builder.addPropertyValue("interface", interfaceClass.getName());
		//下面都是对注解中配置的属性值进行填充 , 至于ServiceBean的作用和这些属性,我们后文再单独分析
        String providerConfigBeanName = service.provider();
        if (StringUtils.hasText(providerConfigBeanName)) {
            addPropertyReference(builder, "provider", providerConfigBeanName);
        }
        
        String monitorConfigBeanName = service.monitor();
        if (StringUtils.hasText(monitorConfigBeanName)) {
            addPropertyReference(builder, "monitor", monitorConfigBeanName);
        }

        String applicationConfigBeanName = service.application();
        if (StringUtils.hasText(applicationConfigBeanName)) {
            addPropertyReference(builder, "application", applicationConfigBeanName);
        }
        
        String moduleConfigBeanName = service.module();
        if (StringUtils.hasText(moduleConfigBeanName)) {
            addPropertyReference(builder, "module", moduleConfigBeanName);
        }

        String[] registryConfigBeanNames = service.registry();
		
		//registries属性 是注册中心配置类的beanName ,将beanName暂时包装为RuntimeBeanReference,后续再从容器中获取bean
        List<RuntimeBeanReference> registryRuntimeBeanReferences = toRuntimeBeanReferences(registryConfigBeanNames);
		
        if (!registryRuntimeBeanReferences.isEmpty()) {
            builder.addPropertyValue("registries", registryRuntimeBeanReferences);
        }
		
        String[] protocolConfigBeanNames = service.protocol();

        List<RuntimeBeanReference> protocolRuntimeBeanReferences = toRuntimeBeanReferences(protocolConfigBeanNames);

        if (!protocolRuntimeBeanReferences.isEmpty()) {
            builder.addPropertyValue("protocols", protocolRuntimeBeanReferences);
        }
		
        Method[] methods = service.methods();
        List<MethodConfig> methodConfigs = MethodConfig.constructMethodConfig(methods);
        if (!methodConfigs.isEmpty()) {
            builder.addPropertyValue("methods", methodConfigs);
        }

        return builder.getBeanDefinition();

    }


    private ManagedList<RuntimeBeanReference> toRuntimeBeanReferences(String... beanNames) {
    	
        ManagedList<RuntimeBeanReference> runtimeBeanReferences = new ManagedList<RuntimeBeanReference>();
	
        if (!ObjectUtils.isEmpty(beanNames)) {

            for (String beanName : beanNames) {
				//如果是占位符形式,解析占位符
                String resolvedBeanName = environment.resolvePlaceholders(beanName);
				//将beanNameb包装为RuntimeBeanReference返回
                runtimeBeanReferences.add(new RuntimeBeanReference(resolvedBeanName));
            }

        }
		
        return runtimeBeanReferences;

    }
	//属性值可以是站位符的形式
    private void addPropertyReference(BeanDefinitionBuilder builder, String propertyName, String beanName) {
        String resolvedBeanName = environment.resolvePlaceholders(beanName);
        builder.addPropertyReference(propertyName, resolvedBeanName);
    }


    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值