Предисловие
Когда мы используем аннотацию @discoveryclient, у нас будет следующий вопрос: почему он выполняет работу по регистрации услуги? Разве это не следует использовать в качестве обнаружения услуг? Давайте подробно рассмотрим его исходный код.
1. Интерфейс жизненного цикла Springframework
Чтобы понять эту проблему, мы должны понять этот важный интерфейс:
/ * * Copyright 2002-2015 Оригинальный автор или авторы. * * Лицензирован по лицензии Apache, версия 2.0 («Лицензия»); * Вы не можете использовать этот файл, кроме как в соответствии с лицензией. * Вы можете получить копию лицензии по адресу * * http://www.apache.org/licenses/license-2.0 * *, если не требуется применимый закон или не согласен в письменной форме, программное обеспечение *, распределено по лицензии, распределяется на «как это», * без гарантий или условий любого рода, либо экспрессии, либо подразумевается. * См. Лицензию для конкретного языка, регулирующих разрешения и * ограничения по лицензии. */package org.springframework.context;/*** Общий интерфейс, определяющий методы для управления жизненным циклом запуска/остановки. * Типичный вариант использования для этого - управление асинхронной обработкой. * <b> ПРИМЕЧАНИЕ. Этот интерфейс не подразумевает конкретную семантику автоматического начала. * Рассмотрим реализацию {@link SmartLifeCycle} для этой цели. </B> * * <p> может быть реализован обоими компонентами (обычно пружинный боб, определяемый в контексте * Spring) и контейнерами (обычно Spring {@link ApplicationContext} * сам). Контейнеры будут распространять сигналы запуска/остановки на все компоненты, которые * применяются в каждом контейнере, например, для сценария остановки/перезапуска во время выполнения. * * <p> может быть использован для прямых вызовов или для управленческих операций через JMX. * В последнем случае {@link org.springframework.jmx.export.mbeanexporter} * обычно определяется с * {@link org.springframework.jmx.export.assembler.InterfacebadeMbeanInfoAssembler}, * ограничиваемой emprotembler-componceccl * * <p> Обратите внимание, что интерфейс жизненного цикла поддерживается только на <b> Singleton * Beans </b>. На любом другом компоненте интерфейс жизненного цикла останется незамеченным * и, следовательно, игнорируется. Кроме того, обратите внимание, что расширенный интерфейс {@link SmartLifeCycle} * обеспечивает интеграцию с фазами запуска и выключения контекста приложения. * * @author Juergen Hoeller * @since 2.0 * @see smartlifecycle * @see configurableapplicationcontext * @see org.springframework.jms.listener.abstractmessagelistenercontainer * @see org.spramework.scheduling.quartzecredactory * @seee org.spramework.scheduling.quartzecrecepractory * seeclebrececrefactory * wergeclebrecquepractory. /*** Начните этот компонент. * <p> не должен бросить исключение, если компонент уже работает. * <p> В случае контейнера это будет распространять начальный сигнал для всех применяемых компонентов *. * @see smartlifecycle#isautostartup () */ void start (); /** * Остановите этот компонент, обычно синхронным образом, так что компонент * полностью останавливается при возврате этого метода. Рассмотрим реализацию {@link SmartLifeCycle} * и его {@Code Stop (Runnable)}, когда необходимо асинхронное поведение остановки. * <p> Обратите внимание, что это уведомление о остановке не гарантируется до разрушения: на * регулярного отключения, {@code Lifecycle} Сначала получит уведомление о остановке до * Образцы общего уничтожения будут распространяться; Тем не менее, на горячем обновлении во время жизни * контекста или на прерываемых попытках обновления, будут вызваны только методы уничтожения. * <p> не должен бросить исключение, если компонент еще не запускается. * <p> В случае контейнера это будет распространять сигнал остановки на все компоненты *, которые применяются. * @see smartlifecycle#stop (runnable) * @see org.springframework.beans.factory.disposablebean#destry () */ void stop (); /*** Проверьте, работает ли этот компонент в настоящее время. * <p> В случае контейнера это вернет {@code true} только в том случае, если <i> все компоненты </i> * применяются в настоящее время. * @return, работает ли компонент в настоящее время */ boolean isrunning ();}Этот интерфейс определяет метод управления жизненным циклом запуска/остановки. Когда пружинный контейнер IOC запускается или останавливается, каждому компоненту будет отправлен сигнал запуска или остановки, поэтому мы можем делать то, что хотим в соответствующем методе. Через диаграмму классов мы можем найти, что мы обычно используем ClassPathxMlapplicationContext Class. Реализует этот интерфейс
Давайте кратко продемонстрируем дело и создадим класс MyLifeCycle:
пакет org.hzgj.spring.study.context; import org.springframework.context.smartlifecycle; открытый класс mylifecycle реализует SmartLifeCycle {@Override public void start () {System.out.println ("myLifeCycle start ...."); } @Override public void stop () {System.out.println ("mylifecycle Stop ....."); } @Override public boolean isrunning () {return false; } @Override public boolean isautostartup () {return true; } @Override public void Stop (Runnable Callback) {} @Override public int getPhase () {System.out.println ("phase"); возврат 10; }}Здесь мы наследуем SmartLifeCycle. Интерфейс наследует жизненный цикл. Метод Isrunning используется для определения того, находится ли текущий компонент в состоянии бега. Обратите внимание, что он может работать только тогда, когда возвратное значение isrunning является ложным.
Мы настраиваем MyLifeCycle в файл конфигурации пружины и запускаем через ClassPathxMlapplicationContext, чтобы получить следующие результаты:
Кроме того, метод getPhase здесь предназначен для определения значения стадии (его можно понимать как приоритет. Чем меньше значение, тем больше выполняется соответствующий жизненный цикл) выполняется сначала)
2. DiscoveryClient Исследование исходного кода
@Enablediscoveyclient
/ * * Copyright 2013-2015 Оригинальный автор или авторы. * * Лицензирован по лицензии Apache, версия 2.0 («Лицензия»); * Вы не можете использовать этот файл, кроме как в соответствии с лицензией. * Вы можете получить копию лицензии по адресу * * http://www.apache.org/licenses/license-2.0 * *, если не требуется применимый закон или не согласен в письменной форме, программное обеспечение *, распределено по лицензии, распределяется на «как это», * без гарантий или условий любого рода, либо экспрессии, либо подразумевается. * См. Лицензию на конкретные разрешения на управление языком и * ограничения по лицензии. */package org.springframework.cloud.client.discovery; import java.lang.annotation.documented; импорт java.lang.annotation.elementtype; импорт java.lang.annotation.inhared; импорт java.lang.Annotation.Timplation. java.lang.annotation.target; import org.springframework.context.annotation.import;/*** Аннотация для включения реализации DiscoveryClient. * @author spencer gibb * /@target (elementtype.type) @retention (artentionpolicy.runtime)@документирован@enhyted@import (enabledIscOveryClientImproseSelector.class) public @Interface enabledIscoveryClient { /** * Если это правда, сертификация будет автоматически регистрировать местный сервер. */ boolean autoregister () по умолчанию true;} Обратите внимание, что @Import(EnableDiscoveryClientImportSelector.class) Мы можем обратиться к этому классу:
/ * * Copyright 2013-2015 Оригинальный автор или авторы. * * Лицензирован по лицензии Apache, версия 2.0 («Лицензия»); * Вы не можете использовать этот файл, кроме как в соответствии с лицензией. * Вы можете получить копию лицензии по адресу * * http://www.apache.org/licenses/license-2.0 * *, если не требуется применимый закон или не согласен в письменной форме, программное обеспечение *, распределено по лицензии, распределяется на «как это», * без гарантий или условий любого рода, либо экспрессии, либо подразумевается. * См. Лицензию для конкретного языка, регулирующих разрешения и * ограничения по лицензии. */package org.springframework.cloud.client.discovery; import org.springframework.boot.bind.relaxedPropertyResolver; импорт org.springframework.cloud.commons.util.springfortoryimportselector; импорт org.spramework.core.ordered; org.springframework.core.annotation.annotationattributes; import org.springframework.core.annotation.order; импорт org.springframework.core.env.configerailityenvironment; импорт org.springframework.core.env.environment; org.springframework.core.env.mapporpertysource; импорт org.springframework.core.type.annotationmetadata; импорт java.util.arraylist; импорт java.util.arrays; import.util.linkedhashmap; импорт java.util.list; */ @Order (orducted.lowest_precedence - 100) открытый класс EnabledIcomPoveryClientImproseSelector Extends SpringFactoryRemortectorector <NabledIscoveryClient> {@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 (новая строка [0]); } else {Environment env = getEnvironment (); if (confinevelyEnvironment.class.isinstance (env)) {настраиваемое настройки среда configenv = (confinevelyEnvironment) env; LinkedHashmap <String, Object> Map = new LinkedHashmap <> (); map.put ("spring.cloud.service-registry.auto-registration.enabled", false); MapPropertySource PropertySource = new MapPropertySource ("SpringClouddiscoveryclient", Map); configenv.getPropertySources (). AddLast (PropertySource); }} return imports; } @Override Protected Boolean Isenabled () {return new RelexedPropertyResolver (getEnvironment ()). GetProperty ("spring.cloud.discovery.enabled", boolean.class, boolean.true); } @Override Protected Boolean HasDefaultFactory () {return true; }} Метод переписывания этого класса поступает из интерфейса ImportSelector. Мы можем отслеживать класс в соответствии с кодом в соответствии с if(autoRegister) : org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration . Давайте посмотрим на структурную диаграмму:
Мы можем знать, что этот класс реализует интерфейс жизненного цикла, поэтому давайте посмотрим на метод начала, который находится в своем родительском классе AbstractDiscoverylifecycle:
/ * * Copyright 2013-2015 Оригинальный автор или авторы. * * Лицензирован по лицензии Apache, версия 2.0 («Лицензия»); * Вы не можете использовать этот файл, кроме как в соответствии с лицензией. * Вы можете получить копию лицензии по адресу * * http://www.apache.org/licenses/license-2.0 * *, если не требуется применимый закон или не согласен в письменной форме, программное обеспечение *, распределено по лицензии, распределяется на «как это», * без гарантий или условий любого рода, либо экспрессии, либо подразумевается. * См. Лицензию для конкретного языка, регулирующих разрешения и * ограничения по лицензии. */package org.springframework.cloud.client.discovery; import java.util.concurrent.atomic.atomicboolean; import java.util.concurrent.atomic.atomicinteger; import javax.annotation.predestroy; import org.apache.log. org.apache.commons.logging.logfactory; import org.springframework.beans.beansexception; import org.springframework.boot.context.embedded.embeddedservletcontainerinitializedevent; import.spramework.cloudsconteNipentevent; Import.SmisterVistermere. org.springframework.cloud.client.serviceRegistry.serviceRegistry; импорт org.springframework.context.applicationContext; импорт org.springframework.cplication.applicationContextAware; импорт org.springFramework.context.Applicationslister; Методы жизненного цикла, которые могут быть полезными и общими для различных реализаций DiscoveryClient. * * @deprecated использовать {@link org.springframework.cloud.client.serviceRegistry.abstractautoserviceRegistration} вместо этого. Этот класс будет удален в следующем поезде. * * @author spencer gibb */ @rececatedpublic абстрактного класса AbstractDiscoverylifecycle реализует DiscoveryLifecycycle, ApplicationContextAware, ApplicationListener <embeddedServletContainErinitializedEvent> {Private Static Final Logger = logfactory.getLog (AbstractDiscoverileCycle.class); Частный логический AutoStartUp = true; Частный Atomicboolean Rune = новый Atomicboolean (false); private int order = 0; частное контекст приложения для контекста; Среда частной среды; Частный порт AtomicInteger = новый AtomicInteger (0); Защищенный ApplicationContext getContext () {return Context; } @Override public void setApplicationContext (ApplicationContext ApplicationContext) Throws BeanSexception {this.context = ApplicationContext; this.environment = this.context.getenvironment (); } @Deprecated защищенная среда getenvironment () {return Environment; } @Deprecated защищенная атомицинтегер getport () {return port; } @Override public boolean isautostartup () {return this.autostartup; } @Override public void Stop (Runnable Callback) {try {stop (); } catch (Exception e) {logger.error («Проблема возникла, пытаясь остановить жизненный цикл обнаружения», E); } callback.run (); } @Override public void start () {if (! ISenabled ()) {if (logger.isdebugenabled ()) {logger.debug ("Lifecycle Discovery отключен. Не запускается"); } возвращаться; } // Установите только порт, если nonsecureport равен 0 и this.port! = 0 if (this.port.get ()! = 0 && getConfiguredPort () == 0) {setConfiguredPort (this.port.get ()); } // только инициализируйте, если nonsecurePort больше 0, и он еще не работает // из -за ContainerPortinitializer ниже if (! this.running.get () && getConfigudPort ()> 0) {Register (); if (supergistermanagement ()) {RegisterManagement (); } this.context.publishevent (новый instanceregisteredevent <> (this, getConfiguration ())); this.running.compareAndset (false, true); }} @Deprecated защищенная абстрактная int int getConfiguredPort (); @Deprecated защищенная абстрактная void setConfiguredPort (int port); / ** * @return, если служба управления следует зарегистрировать в {@link serviceRegistry} */ protected boolean supregistermanagement () {return getManagementPort ()! = NULL && ManagementServerPortutils.isdifferent (this.context); } / ** * @return Объект, используемый для настройки регистрации * / @deprecated защищенный абстрактный объект getConfiguration (); / ** * Зарегистрировать локальную службу с помощью DiscoveryClient */ Protected Abstract void Register (); / ** * Зарегистрируйте локальную службу управления с помощью DiscoveryClient */ Protected void Registermanagement () {}/ ** * Де-регистрация локальной службы с помощью DiscoveryClient */ Защищенный абстрактный dereGister (); / ** * DE-регистрация локальной службы управления с помощью DiscoveryClient */ Protected void dereGisterManagement () {}/ ** * @return true, если {@link DiscoveryLifeCycycle} включена */ Защищенная абстрактная логическая подразделение (); / ** * @return ServiceId службы управления */ @deprecated защищенная строка getmanagementserviceid () {// todo: настраиваемое суффикс управления вернуть это.context.getid () + ": Management"; } / ** * @return Имя службы службы управления * / @deprecated защищенная строка getmanagementerviceName () {// todo: настраиваемая суффикс управления return getAppname () + ": Management"; } / ** * @return Порт сервера управления * / @deprecated защищенное целое число getManagementPort () {return ManagementServerPortutils.getport (this.context); } / ** * @return Имя приложения, в настоящее время Spring.Application.name свойство * / @deprecated защищенная строка getAppname () {return this.environment.getProperty ("Spring.Application.name", "Application"); } @Override public void stop () {if (this.running.compareAndset (true, false) && isenabled ()) {dereGister (); if (должен (wupergistermanagement ()) {dereGisterManagement (); }}} @Predestroy public void destress () {stop (); } @Override public boolean isrunning () {return this.running.get (); } Защищенный атомабуолевый getRunning () {return running; } @Override public int getOrder () {return this.order; } @Override public int getPhase () {return 0; } @Override @deprecated public void onapplicationEvent (EmbeddedServletContainerInitializeVent Event) {// todo: take ssl во внимание // Не регистрируйте порт управления как порт if (! ". event.getembeddedservletcontainer (). getport ()); this.start (); }}}Обратите внимание, что в методе начала есть часть этого кода:
if (! this.running.get () && getConfiguredPort ()> 0) {Register (); if (supergistermanagement ()) {RegisterManagement (); } this.context.publishevent (новый instanceregisteredevent <> (this, getConfiguration ())); this.running.compareAndset (false, true); } Обратите внимание register() является абстрактным методом в этом классе. Итак, давайте посмотрим на код в классе AbstractautoServiceReartionaltion, и я буду публиковать только ключевые части здесь:
// ..... Защищенная абстрактная AbstractoServiceRegistration (ServiceRegistry <r> ServiceRegistry, AutoServiceRegistrationProperties Properties) {this.serviceRegistry = ServiceRegistry; this.properties = свойства; } //........../** * Зарегистрировать локальную службу с помощью {@link ServiceRegistry} */@Override Protected void Register () {this.serviceRegistry.register (getRegistration ()); }Мы можем обнаружить, что в конструкторе передается тип ServiceRegistry, который является интерфейсом SpringCloud, который предоставляет нам для регистрации обслуживания. Здесь EurekaserviceRegistry реализует этот интерфейс:
/ * * Copyright 2013-2016 Оригинальный автор или авторы. * * Лицензирован по лицензии Apache, версия 2.0 («Лицензия»); * Вы не можете использовать этот файл, кроме как в соответствии с лицензией. * Вы можете получить копию лицензии по адресу * * http://www.apache.org/licenses/license-2.0 * *, если не требуется применимый закон или не согласен в письменной форме, программное обеспечение *, распределено по лицензии, распределяется на «как это», * без гарантий или условий любого рода, либо экспрессии, либо подразумевается. * См. Лицензию для конкретного языка, регулирующих разрешения и * ограничения по лицензии. *//package org.springframework.cloud.netflix.eureka.serviceRegistry; импорт java.util.hashmap; import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; import org.spramework.client.serficeRICISTRICISTRICISTORY; ImportRICERICIRICISTRICISRICISTORIO com.netflix.appinfo.instanceinfo;/** * @author spencer gibb */public class eurekaserviceRegistry реализует ServiceRegistry <eurekaregistration> {Private Static Final Log = logfactory.getLog (eurekaservicereGistry.class); @Override public void Register (eurekaregistration reg) {возможно, initializeclient (reg); if (log.isinfoenabled ()) {log.info ("регистрация приложения" + reg.getinstanceConfig (). getAppName () + "со статусом" + reg.getInstanceConfig (). getInitialStatus ()); } reg.getApplicationInfomanager () .setInstanceStatus (reg.getInstanceConfig (). getInitialStatus ()); if (reg.gethealthcheckhandler ()! = null) {reg.geteurekaclient (). RegisterHealthCheck (reg.getHealthCheckHandler ()); }} private void, возможно, Iinitializeclient (eurekaregistration reg) {// инициализация сил возможных прокси -прокси -серверов. reg.geteurekaclient (). getApplications (); } @Override public void deregister (eurekaregistration reg) {if (reg.getApplicationInfomanager (). GetInfo ()! = Null) {if (log.isinfoEnabled ()) {log.info ("ungistering application" + reg.getinstanceconfig () getAppname (") с eaure"; } reg.getApplicationInfomanager (). setInstanceStatus (exanceinInfo.instanceStatus.down); // Выключение клиента Eureka должно произойти с eurekaregistration.close () // Авто регистрация создаст компонент, который будет должным образом распределен // Ручные регистрации должны вызвать Close ()}} @Override public void settatus (eurekaregistration, строковая статус) {exactorInfo info = info = registration.getApplicationInfomanager (). getInfo (); // TODO: Как правильно справиться с удалением? if ("cancel_override". EqualsIgnoreCase (status)) {Registration.getEureKaclient (). CancelOverridestatus (info); возвращаться; } // todo: как иметь дело с типами статуса в разных системах обнаружения? ExanceminInfo.instanceStatus newStatus = exanceinInfo.instancestatus.toenum (status); registration.geteurekaclient (). SetStatus (NewStatus, Info); } @Override public Object getStatus (eurekaregistration Registration) {hashmap <string, object> status = new hashmap <> (); ExactionInfo info = registration.getApplicationInfomanager (). GetInfo (); status.put ("status", info.getStatus (). toString ()); status.put ("overdenStatus", info.getOverriddenStatus (). ToString ()); Статус возврата; } public void close () {}}Таким образом, мы можем суммировать следующие моменты:
1. Использование @discoveryclient для регистрации Сервиса использует механизм жизненного цикла, а метод ServiceRegistry register() будет выполняться при запуске контейнера.
2. Использование @discoveryclient более гибко, чем @enableeurekaclient и @enableteurekaserver, потому что он блокирует реализацию регистрации обслуживания, и мы можем даже настроить регистрационный центр.
3. Это также автоматически найдет реализацию интерфейса DiscoveryClient для обнаружения услуг.
3. DiscoveryClient практического регистрационного центра Redis
Ниже мы выполняем требование, основанное на REDIS в качестве регистрационного центра для понимания DiscoveryClient. Кстати, давайте поймем важные интерфейсы Springcloud: ServiceRegistry, ServiceInstance. До этого мы добавим поддержку Redis:
Группа компиляции: 'org.springframework.boot', имя: 'Spring-Boot-Starter-Data-Redis'
1. Реализовать интерфейс регистрации
пакет com.hzgj.lyrk.member; импорт org.springframework.beans.factory.annotation.value; import org.springframework.cloud.client.serviceRegistry.registration; импорт org.springframework.stereotype.component; import -java.net.net.net.net.netem.net ;nethips.net; java.net.uri; import java.util.enumeration; import java.util.map; @componentpublic class redisrecistration реализует регистрацию {@value ("$ {server.port}") частный целовый порт; @Value ("$ {Spring.Application.name}") Private String ApplicationName; частный хост строки; public void sethost (string host) {this.host = host; } public void setport (целое число порта) {this.port = port; } public void setApplicationName (String ApplicationName) {this.ApplicationName = ApplicationName; } @Override public String getServiceId () {return ApplicationName + ":" + gethost () + ":" + getPort (); } @Override public String gethost () {try {if (host == null) return getlocalhostlanaddress (). Gethostaddress (); еще вернуть хост; } catch (Exception e) {e.printstackTrace (); } return null; } @Override public int getPort () {return Port; } @Override public boolean issecure () {return false; } @Override public uri geturi () {return null; } @Override public map <string, string> getMetAdata () {return null; } public String getServiceName () {return this.ApplicationName; } public inetAddress getLocalhostlanAddress () бросает исключение {try {inetAddress candidateaddress = null; // Переносить все сетевые интерфейсы для (enumeration ifaces = networkInterface.getNetworkInterfaces (); ifaces.hasmoreElements ();) {networkInterface iface = (networkInterface) ifaces.nextElement (); // Переносить IP во всех интерфейсах для (перечисление inetaddrs = iface.getinetAddresses (); inetAddrs.hasmoreElements ();) {inetAddress inetAddr = (inetAddress) inetaddrs.nextelement (); if (! inetaddr.isloopbackAddress ()) {// исключить адрес типа Loopback if (inetAddr.issiteLocalAddress ()) {// Если это сайт-локальный адрес, это возврат inetAddr; } else if (candidateaddress == null) {// Адрес сайта-локального типа не был найден, сначала запишите адрес кандидата Candidateaddress = inetaddr; }}}}} if (candidateaddress! = null) {return candidateaddress; } // Если не найден адрес без петли, вы можете использовать только наиболее выбранное решение. InetAddress jdksuppliedaddress = inetaddress.getlocalhost (); вернуть jdksuppliedaddress; } catch (Exception e) {e.printstackTrace (); } return null; }}Этот интерфейс наследует ServiceIntance, поэтому основная функция этого интерфейса состоит в том, чтобы определить спецификации экземпляра службы, например, что является его ServiceID, что такое номер порта и т. Д.
2. Реализуйте интерфейс ServiceRegistry
Пакет com.hzgj.lyrk.member; import org.springframework.beans.factory.annotation.autowired; import org.springframework.cloud.client.serviceRegistry.serviceRegeristry; imporm.springframework.data.redis.ceringsredistraste ServiceRegistry <Redisregistration> {@autowired Private StringRedistemplate Redistemplate; @Override public void Register (Registration Registration) {String serviceId = registration.getServiceId (); redistemplate.opforlist (). Leathpush (serviceId, registration.gethost () + ":" + registration.getport ()); } @Override public void dereGister (Registration Registration) {redistemplate.opforlist (). Remove (registration.getserviceid (), 1, registration.gethost () + ":" + registration.getport ()); } @Override public void cloid () {//redistemplate.d System.out.println ("rowcle ..."); } @Override public void setStatus (redisRegistration Registration, String Status) {} @Override public <t> t getStatus (регистрация RedIsRegistration) {return null; }}Основная функция этого интерфейса - определить, как зарегистрировать, отменить службу, установить и получить статус службы и т. Д.
3. Унаследованная абстрактная класс.
package com.hzgj.lyrk.member;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;import org.springframework.cloud.client.serviceRegistry.serviceRegistry; открытый класс RedisautoServiceRegistration расширяет AbstractautoServiceRegistration <RedisRegistration> {@Autowired Private RedIsRegistration REDISREGISTRATIONS; Защищенная redisautoserviceRegistration (ServiceRegistry <RediSregistraitary> ServiceRegistry, AutoServiceRegistrationProperties Properties) {Super (ServiceRegistry, Properties); // ServiceRegistry.register (getRegistration ()); } @Override Protected int getConfigudPort () {return redisRegistration.getPort (); } @Override Protected void setConfiguredPort (int port) {} @Override защищенный объект getConfiguration () {return null; } @Override Protected Boolean Isenabled () {return true; } @Override Protected RediSregistration getRegistration () {return RedIsRegistration; } @Override защищено redisRegistration getManagemagementRegistration () {return null; }}4. Определите класс реализации DiscoveryClient RedisDiscoveryclient
пакет com.hzgj.lyrk.member; import org.apache.commons.lang.stringutils; import org.springframework.beans.factory.annotation.autowired; импорт org.springframework.cloud.client.serviceinstance. org.springframework.data.redis.core.stringredistemplate; import java.util.arraylist; импорт java.util.list; импорт java.util.function.function; импорт java.util.stream.collectors; public classdiscoveryclient Imptementience ucipplience {@AutoWaRETERTERTERTORTERS; @Override public String description () {return "Обнаружение службы в регистрационном центре Redis"; } @Override Public ServiceInstance getLocalServiceInstance () {return null; } @Override public list <serviceInsance> getInstances (String serviceId) {return redistemplate.opforlist (). Range (ServiceId, 0, -1). parallelstream (). Map ((function <string, serviceInstance>) s -> {redisRegistration redIsregistration = new RedisRegistrastraital (); RedIsRegistristristrastristrastrication.SetApplicationName (serviceId); string hostname = stringUtils.split (s, ":") [0]; String port = stringn.split (s, ") [1]; RedisRegistration.sethost (HostName); } @Override public list <string> getServices () {list <string> list = new ArrayList <> (); list.addall (redistemplate.keys ("*")); вернуть список; }}Этот класс в основном предназначен для обнаружения услуг Редис -регистрационного центра
5. Определите автоматические классы сборки для создания соответствующих бобов
Пакет com.hzgj.lyrk.member; import org.springframework.boot.autoconfigure.condition.conditionalonProperty; import org.springframework.boot.context.properties.enableConfigurationProperties; import.boot.context.properties.enableconfigurationproperties; org.springframework.cloud.client.serviceRegistry.autoserviceRegistrationPerties; Import org.springframework.context.annotation.bean; импорт org.springframework.context.annotation.configuration; импорт org.springframework.context.annotation.primary;@configuration@ounableconfigurationproperties (redisconfig.class) @conditionalonproperty (value = "spring.redis.egistry.enabled", matchifmissing = true) public redisrecistryautoconfiguration. Redisconfig) {System.out.println (redisconfig.gethost ()); вернуть новую redisserviceRegistry (); } @Bean RedisautoServiceRegistration RedisautoServiceRegistration (RedisserviceRegistry rediSserviceRegistry) {return new RedisautoServicereGistration (RedisserviceRegistry, New AutoServiceRegistrationPerties ()); } @Bean @primary Redisdiscoveryclient redisdiscoveryclient () {return new redisdiscoveryclient (); }}6. Определите класс запуска
пакет com.hzgj.lyrk.member; import org.springframework.boot.springapplication; импорт org.springframework.boot.autoconfigure.springbootapplication; импорт org.springframework.clid.client.discovery.discoverycliat org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration;import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration;import org.springframework.context.configurableapplicationcontext;@enablediscoveryclient@springbootapplication (exklide = {simplediscoveryclientautoconfiguration.class, compositedIscOveryClientAutoConfiguration.Class}) public class kemb ApplicationContext = SpringApplication.run (memberApplication.class, args); DiscoveryClient DiscoveryClient = ApplicationContext.getBean (DiscoveryClient.class); DiscoveryClient.getServices (). Foreach (Action -> {System.out.println (action);}); }}Здесь сборка DiscoveryClient по умолчанию исключена в аннотации SpringBootApplication.
Когда мы успешно запустим, мы можем обнаружить, что консоль выводит соответствующее имя и адрес службы:
Мы снова генерируем файл JAR через упаковку Gradle и запускаем:
Java -Jar Член-Server-0.0.1-snapshot.jar-server.port = 8800
Мы видим, что зарегистрированное значение услуги, которое было кэшировано в Редисе:
Суммировать
Вышеуказанное - все содержание этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.