通过前面文章的分析EurekaClientAutoConfiguration类中EurekaClientConfigBean和EurekaInstanceConfigBean的配置属性说明,我们在看看EurekaServiceRegistry这个类bean的注入,进入该类我们看到它实现了ServiceRegistry接口
这个接口是我们spring cloud提供的用于服务注册的接口,在接口上面它同时提供了EurekaRegistration实例对象的依赖,进入到EurekaRegistration类可以了解到该类实现了Registration接口
通过代码我们发现它实现了接口中返回值的信息初始化,同时在其内部类Builder中在对象没有初始化的时候初始化对象赋值,并返回EurekaRegistration对象。
public EurekaRegistration build() { Assert.notNull(instanceConfig, "instanceConfig may not be null"); if (this.applicationInfoManager == null) { InstanceInfo instanceInfo = new InstanceInfoFactory() .create(this.instanceConfig); this.applicationInfoManager = new ApplicationInfoManager( this.instanceConfig, instanceInfo); } if (this.eurekaClient == null) { Assert.notNull(this.clientConfig, "if eurekaClient is null, EurekaClientConfig may not be null"); Assert.notNull(this.publisher, "if eurekaClient is null, ApplicationEventPublisher may not be null"); this.eurekaClient = new CloudEurekaClient(this.applicationInfoManager, this.clientConfig, this.publisher); } return new EurekaRegistration(instanceConfig, eurekaClient, applicationInfoManager, healthCheckHandler); }
我们在回到EurekaServiceRegistry类中,可以看到它有以下方法
它实现了服务注册,取消注册,状态设置等方法,我们先分析下register()方法:
通过私有方法maybeInitializeClient()获取当前注册的实例对象以及服务器上面返回的所有注册信息
private void maybeInitializeClient(EurekaRegistration reg) { // force initialization of possibly scoped proxies reg.getApplicationInfoManager().getInfo(); reg.getEurekaClient().getApplications(); }
最后在register()方法里面设置状态为UP及健康检查的连接地址。在deregister()方法中则只是将状态值设置为DOWN作为注销标志。
接下来我们了解下ApplicationInfoManager bean的注入,它通过我们前面已经注入过的EurekaClientConfigBean获取client配置信息,通过InstanceInfoFactory类的create()方法将配置信息复制到Netflix的InstanceInfo对象中,然后将InstanceInfo对象传递给ApplicationInfoManager,进入到ApplicationInfoManager类,看看它的结果如下图
根据上面的方法我们主要看下重要的一些实现
1.initComponent()
该方法是初始化EurekaInstanceConfig和InstanceInfo对象,这个方法主要用在非bean注入方式的时候,在获取InstanceInfo对象对象的时候,我们可以了解到EurekaConfigBasedInstanceInfoProvider类是单例模式的,同时get()方法是同步实现的。
2.StatusChangeListener
这个类相关的目前没有看到有任何的实现,所以相关的方法就不介绍了
3.refreshDataCenterInfoIfRequired()
这个方法从名称可以知道是刷新数据中心信息的,它用于表示新的数据连接地址被配置了,把当前实例对象设置为脏数据,然后在相应的应用引用的时候重新进行配置
public void refreshDataCenterInfoIfRequired() { String existingAddress = instanceInfo.getHostName(); String existingSpotInstanceAction = null; if (instanceInfo.getDataCenterInfo() instanceof AmazonInfo) { existingSpotInstanceAction = ((AmazonInfo) instanceInfo.getDataCenterInfo()).get(AmazonInfo.MetaDataKey.spotInstanceAction); } String newAddress; if (config instanceof RefreshableInstanceConfig) { // Refresh data center info, and return up to date address newAddress = ((RefreshableInstanceConfig) config).resolveDefaultAddress(true); } else { newAddress = config.getHostName(true); } String newIp = config.getIpAddress(); if (newAddress != null && !newAddress.equals(existingAddress)) { logger.warn("The address changed from : {} => {}", existingAddress, newAddress); updateInstanceInfo(newAddress, newIp); } if (config.getDataCenterInfo() instanceof AmazonInfo) { String newSpotInstanceAction = ((AmazonInfo) config.getDataCenterInfo()).get(AmazonInfo.MetaDataKey.spotInstanceAction); if (newSpotInstanceAction != null && !newSpotInstanceAction.equals(existingSpotInstanceAction)) { logger.info(String.format("The spot instance termination action changed from: %s => %s", existingSpotInstanceAction, newSpotInstanceAction)); updateInstanceInfo(null , null ); } } } private void updateInstanceInfo(String newAddress, String newIp) { // :( in the legacy code here the builder is acting as a mutator. // This is hard to fix as this same instanceInfo instance is referenced elsewhere. // We will most likely re-write the client at sometime so not fixing for now. InstanceInfo.Builder builder = new InstanceInfo.Builder(instanceInfo); if (newAddress != null) { builder.setHostName(newAddress); } if (newIp != null) { builder.setIPAddr(newIp); } builder.setDataCenterInfo(config.getDataCenterInfo()); instanceInfo.setIsDirty(); }
3.refreshLeaseInfoIfRequired()
这个方法是指过期时间的刷新,当配置的过期时间与默认配置的不相同时就进行刷新操作。
public void refreshLeaseInfoIfRequired() { LeaseInfo leaseInfo = instanceInfo.getLeaseInfo(); if (leaseInfo == null) { return; } int currentLeaseDuration = config.getLeaseExpirationDurationInSeconds(); int currentLeaseRenewal = config.getLeaseRenewalIntervalInSeconds(); if (leaseInfo.getDurationInSecs() != currentLeaseDuration || leaseInfo.getRenewalIntervalInSecs() != currentLeaseRenewal) { LeaseInfo newLeaseInfo = LeaseInfo.Builder.newBuilder() .setRenewalIntervalInSecs(currentLeaseRenewal) .setDurationInSecs(currentLeaseDuration) .build(); instanceInfo.setLeaseInfo(newLeaseInfo); instanceInfo.setIsDirty(); } }
以上就是本节的主要内容,我们主要了解了EurekaServiceRegistry和ApplicationInfoManager 这2个类的注入,后面章节我们继续剩下的类的注入讲解。