码迷,mamicode.com
首页 > 编程语言 > 详细

【spring cloud】源码分析(一)

时间:2017-09-23 14:34:25      阅读:922      评论:0      收藏:0      [点我收藏+]

标签:null   eureka   classname   ice   factor   string   ade   end   ring   

概述

       从服务发现注解

   @EnableDiscoveryClient入手,剖析整个服务发现与注册过程

一,spring-cloud-common包

       针对服务发现,本jar包定义了

       DiscoveryClient 接口

public interface DiscoveryClient {
    /**
     * A human readable description of the implementation, used in HealthIndicator
     * @return the description
     */
    String description();
    /**
     * @deprecated use the {@link org.springframework.cloud.client.serviceregistry.Registration} bean instead
     *
     * @return ServiceInstance with information used to register the local service
     */
    @Deprecated
    ServiceInstance getLocalServiceInstance();
    /**
     * Get all ServiceInstances associated with a particular serviceId
     * @param serviceId the serviceId to query
     * @return a List of ServiceInstance
     */
    List<ServiceInstance> getInstances(String serviceId);
    /**
     * @return all known service ids
     */
    List<String> getServices();

}

        EnableDiscoveryClient注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableDiscoveryClientImportSelector.class)     //关键在这句话
public @interface EnableDiscoveryClient {
    /**
     * If true, the ServiceRegistry will automatically register the local server.
     */
    boolean autoRegister() default true;
}
@Import注解:支持导入普通的java类,并将其声明成一个bean
现在看EnableDiscoveryClientImportSelector类实现
@Order(Ordered.LOWEST_PRECEDENCE - 100)     //指定实例化bean的顺序
public class EnableDiscoveryClientImportSelector
        extends SpringFactoryImportSelector<EnableDiscoveryClient> {

    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        String[] imports = super.selectImports(metadata);

        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                metadata.getAnnotationAttributes(getAnnotationClass().getName(), true));

        boolean autoRegister = attributes.getBoolean("autoRegister");

        if (autoRegister) {
            List<String> importsList = new ArrayList<>(Arrays.asList(imports));
            importsList.add("org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration");
            imports = importsList.toArray(new String[0]);
        }

        return imports;
    }
EnableDiscoveryClientImportSelector类继承SpringFactoryImportSelector类,该类是重点,如下:
public abstract class SpringFactoryImportSelector<T>
        implements DeferredImportSelector, BeanClassLoaderAware, EnvironmentAware {

    private ClassLoader beanClassLoader;

    private Class<T> annotationClass;

    private Environment environment;

    private final Log log = LogFactory.getLog(SpringFactoryImportSelector.class);

    @SuppressWarnings("unchecked")
    protected SpringFactoryImportSelector() {
        this.annotationClass = (Class<T>) GenericTypeResolver
                .resolveTypeArgument(this.getClass(), SpringFactoryImportSelector.class);
    }

    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        if (!isEnabled()) {
            return new String[0];
        }
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                metadata.getAnnotationAttributes(this.annotationClass.getName(), true));

        Assert.notNull(attributes, "No " + getSimpleName() + " attributes found. Is "
                + metadata.getClassName() + " annotated with @" + getSimpleName() + "?");

        // Find all possible auto configuration classes, filtering duplicates    重点在这个地方
        List<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader
                .loadFactoryNames(this.annotationClass, this.beanClassLoader)));

        if (factories.isEmpty() && !hasDefaultFactory()) {
            throw new IllegalStateException("Annotation @" + getSimpleName()
                    + " found, but there are no implementations. Did you forget to include a starter?");
        }

        if (factories.size() > 1) {
            // there should only ever be one DiscoveryClient, but there might be more than
            // one factory
            log.warn("More than one implementation " + "of @" + getSimpleName()
                    + " (now relying on @Conditionals to pick one): " + factories);
        }

        return factories.toArray(new String[factories.size()]);
    }

SpringFactoriesLoader调用loadFactoryNames其实加载META-INF/spring.factories下的class。

spring-cloud-netflix-eureka-client\src\main\resources\META-INF\spring.factories中配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.cloud.netflix.eureka.config.EurekaClientConfigServerAutoConfiguration,org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceAutoConfiguration,org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration

org.springframework.cloud.bootstrap.BootstrapConfiguration=org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceBootstrapConfiguration

org.springframework.cloud.client.discovery.EnableDiscoveryClient=org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration

该类调用了DeferredImportSelector接口,即ImportSelector接口

,继承了selectImport方法,关于ImportSelector的具体作用,参考下面链接

  http://www.jianshu.com/p/7fd7eeeccad0

  对于selectImport的调用,是在spring context 包中的ConfigurationClassParser进行解析

 

先流程走到EurekaClientAutoConfiguration类与EurekaDiscoveryClientConfiguration类

 

【spring cloud】源码分析(一)

标签:null   eureka   classname   ice   factor   string   ade   end   ring   

原文地址:http://www.cnblogs.com/lodor/p/7580887.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!