全是幹貨的 Java 技術倉庫:
- https://github.com/Wasabi1234/Java-Interview-Tutorial
- 服務注冊發現示意圖
-
開發SpringCloud微服務三年,我才知道@EnableEurekaServer注解到底做了什麼(上)EurekaServerAutoConfiguration#jerseyFilterRegistrationApplicationResource#addInstance - 當你在啟動類上添加了啟動 Eureka 服務注冊中心注解時,到底發生了什麼呢?
-
開發SpringCloud微服務三年,我才知道@EnableEurekaServer注解到底做了什麼(上)EurekaServerAutoConfiguration#jerseyFilterRegistrationApplicationResource#addInstance - 激活eureka伺服器相關配置EurekaServerAutoConfiguration的注解
-
開發SpringCloud微服務三年,我才知道@EnableEurekaServer注解到底做了什麼(上)EurekaServerAutoConfiguration#jerseyFilterRegistrationApplicationResource#addInstance - EurekaServerMarkerConfiguration
-
開發SpringCloud微服務三年,我才知道@EnableEurekaServer注解到底做了什麼(上)EurekaServerAutoConfiguration#jerseyFilterRegistrationApplicationResource#addInstance - 點選到這裡,我們發現 spring.factories檔案
-
開發SpringCloud微服務三年,我才知道@EnableEurekaServer注解到底做了什麼(上)EurekaServerAutoConfiguration#jerseyFilterRegistrationApplicationResource#addInstance - 注意到如下注解
-
開發SpringCloud微服務三年,我才知道@EnableEurekaServer注解到底做了什麼(上)EurekaServerAutoConfiguration#jerseyFilterRegistrationApplicationResource#addInstance
@ConditionalOnBean - 條件注入
也就是當有EurekaServerMarkerConfiguration.Marker.class時,才會注入
是以@EnableEurekaServer就是個開關,隻要寫了該注解,spring 就會幫你把
EurekaServerAutoConfiguration類注入進來。
那麼為什麼注入他就行了?
EurekaServerAutoConfiguration#jerseyFilterRegistration
注意如下類:
ApplicationResource#addInstance
相當于 MVC 中的 controller
/**
* Registers information about a particular instance for an
* {@link com.netflix.discovery.shared.Application}.
*
* @param info
* {@link InstanceInfo} information of the instance.
* @param isReplication
* a header parameter containing information whether this is
* replicated from other nodes.
*/
@POST
@Consumes({"application/json", "application/xml"})
public Response addInstance(InstanceInfo info,
@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {
logger.debug("Registering instance {} (replication={})", info.getId(), isReplication);
// validate that the instanceinfo contains all the necessary required fields
if (isBlank(info.getId())) {
return Response.status(400).entity("Missing instanceId").build();
} else if (isBlank(info.getHostName())) {
return Response.status(400).entity("Missing hostname").build();
} else if (isBlank(info.getIPAddr())) {
return Response.status(400).entity("Missing ip address").build();
} else if (isBlank(info.getAppName())) {
return Response.status(400).entity("Missing appName").build();
} else if (!appName.equals(info.getAppName())) {
return Response.status(400).entity("Mismatched appName, expecting " + appName + " but was " + info.getAppName()).build();
} else if (info.getDataCenterInfo() == null) {
return Response.status(400).entity("Missing dataCenterInfo").build();
} else if (info.getDataCenterInfo().getName() == null) {
return Response.status(400).entity("Missing dataCenterInfo Name").build();
}
// handle cases where clients may be registering with bad DataCenterInfo with missing data
DataCenterInfo dataCenterInfo = info.getDataCenterInfo();
if (dataCenterInfo instanceof UniqueIdentifier) {
String dataCenterInfoId = ((UniqueIdentifier) dataCenterInfo).getId();
if (isBlank(dataCenterInfoId)) {
boolean experimental = "true".equalsIgnoreCase(serverConfig.getExperimental("registration.validation.dataCenterInfoId"));
if (experimental) {
String entity = "DataCenterInfo of type " + dataCenterInfo.getClass() + " must contain a valid id";
return Response.status(400).entity(entity).build();
} else if (dataCenterInfo instanceof AmazonInfo) {
AmazonInfo amazonInfo = (AmazonInfo) dataCenterInfo;
String effectiveId = amazonInfo.get(AmazonInfo.MetaDataKey.instanceId);
if (effectiveId == null) {
amazonInfo.getMetadata().put(AmazonInfo.MetaDataKey.instanceId.getName(), info.getId());
}
} else {
logger.warn("Registering DataCenterInfo of type {} without an appropriate id", dataCenterInfo.getClass());
}
}
}
registry.register(info, "true".equals(isReplication));
return Response.status(204).build(); // 204 to be backwards compatible
}
注意如下繼承體系圖